[swift-evolution] Type Safe Algorithms

James Campbell james at supmenow.com
Wed Jan 6 10:04:45 CST 2016


Seem like the protocol I implemented is actually a Box, so perhaps just
adding a box type would allow us to do most of these things.

https://github.com/robrix/Box

On Wed, Jan 6, 2016 at 4:02 PM, Félix Cloutier <felixcca at yahoo.ca> wrote:

> 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
>
> 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
> +44 7523 279 698
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>


-- 
 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/5192c558/attachment.html>


More information about the swift-evolution mailing list