[swift-evolution] Type Safe Algorithms

James Campbell james at supmenow.com
Wed Jan 6 09:17:23 CST 2016


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
+44 7523 279 698
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160106/ebd6359e/attachment.html>


More information about the swift-evolution mailing list