[swift-evolution] Type Safe Algorithms
Félix Cloutier
felixcca at yahoo.ca
Wed Jan 6 10:02:31 CST 2016
There are lots of people who had an idea like this one, the latest just yesterday, where the other threads had been collected: https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160104/005353.html <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160104/005353.html>
So there's definitely a lot of interest in that.
Freshly out of engineering school, I really liked how my calculator handled that (a bulky old TI Voyage 200, though I think that the N-Spire line can do it too).
Félix
> Le 6 janv. 2016 à 10:17:23, James Campbell via swift-evolution <swift-evolution at swift.org> a écrit :
>
> I implemented a way of type safeing a calculation in Swift. I.e marking an Int as a Degree and then being able to convert to a Radian. (At the bottom of the page)
>
> The magic for these special structs was the AngleType protocol which allows you to Box up a value (in this case a number) and it handles the Conversion (Apart from two of the methods which I had to implement).
>
> In theory we could abstract this protocol out, so that others could use it in the library. Then they just use it with their structs and they can handle converting between these types.
>
> So two questions do we have something like this already? and if not would this be useful ?
>
> import Foundation
>
>
>
> //MARK:- AngleType
>
>
>
> protocol AngleType: FloatLiteralConvertible, IntegerLiteralConvertible {
>
>
> var value: Double { get set }
>
>
> init(_ value: Double)
>
> init(_ value: Int)
>
> init<T: IntegerType>(integerLiteral value: T)
>
> init<T: FloatingPointType>(floatLiteral value: T)
>
> }
>
>
>
> // Implement FloatLiteralConvertible and IntegerLiteralConvertible
>
>
>
> extension AngleType {
>
>
>
> init<T: IntegerType>(integerLiteral value: T)
>
> {
>
> self.init(value)
>
> }
>
>
> init<T: IntegerType>(_ value: T)
>
> {
>
> self.init(integerLiteral: value)
>
> }
>
>
> init<T: FloatingPointType>(floatLiteral value: T)
>
> {
>
> self.init(value)
>
> }
>
>
> init<T: FloatingPointType>(_ value: T)
>
> {
>
> self.init(floatLiteral: value)
>
> }
>
> }
>
>
>
> //MARK:- Degree
>
>
>
> struct Degree: AngleType {
>
>
> typealias FloatLiteralType = Double
>
> typealias IntegerLiteralType = Int
>
>
> var value: Double
>
>
> init(_ value: Double) {
>
> self.value = value
>
> }
>
>
> init(_ value: Int) {
>
> self.value = Double(value)
>
> }
>
> }
>
>
>
> protocol DegreeConvertiable {
>
> init(degreeLiteral value: Degree)
>
> }
>
>
>
> extension Degree: CustomStringConvertible, CustomDebugStringConvertible {
>
> var description: String {
>
> return self.value.description
>
> }
>
>
> var debugDescription: String {
>
> return "\(self.value.description)°"
>
> }
>
> }
>
>
>
> extension Degree: RadianConvertiable {
>
> init(radianLiteral value: Radian) {
>
> self.value = Double(radianLiteral:value) * 180.0 / M_PI
>
> }
>
>
> init(_ value: Radian) {
>
> self.init(radianLiteral: value)
>
> }
>
> }
>
>
>
> //MARK:- Radian
>
>
>
> struct Radian: AngleType {
>
>
> typealias FloatLiteralType = Double
>
> typealias IntegerLiteralType = Int
>
>
> var value: Double
>
>
> init(_ value: Double) {
>
> self.value = value
>
> }
>
>
> init(_ value: Int) {
>
> self.value = Double(value)
>
> }
>
> }
>
>
>
> protocol RadianConvertiable {
>
> init(radianLiteral value: Radian)
>
> }
>
>
>
> extension Radian: CustomStringConvertible, CustomDebugStringConvertible {
>
> var description: String {
>
> return self.value.description
>
> }
>
>
> var debugDescription: String {
>
> return "\(self.value.description)㎭"
>
> }
>
> }
>
>
>
> extension Radian: DegreeConvertiable {
>
> init(degreeLiteral value: Degree) {
>
> self.value = Double(degreeLiteral: value) * M_PI / 180.0
>
> }
>
>
> init(_ value: Degree) {
>
> self.init(degreeLiteral: value)
>
> }
>
> }
>
>
>
> //MARK:- Adding Conformance To Built In Types
>
>
>
> extension FloatLiteralType: DegreeConvertiable, RadianConvertiable
>
> {
>
> init(degreeLiteral degree: Degree) {
>
> self.value = degree.value.value
>
> }
>
>
> init(radianLiteral radian: Radian) {
>
> self.value = radian.value.value
>
> }
>
> }
>
>
>
> extension CGFloat: DegreeConvertiable, RadianConvertiable
>
> {
>
> init(degreeLiteral degree: Degree) {
>
> self.init(degree.value)
>
> }
>
>
> init(radianLiteral radian: Radian) {
>
> self.init(radian.value)
>
> }
>
>
> init(_ degree: Degree) {
>
> self.init(degreeLiteral: degree)
>
> }
>
>
> init(_ radian: Radian) {
>
> self.init(radianLiteral: radian)
>
> }
>
> }
>
> --
> Wizard
> james at supmenow.com <mailto:james at supmenow.com>
> +44 7523 279 698
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160106/5b9187ea/attachment.html>
More information about the swift-evolution
mailing list