<div dir="ltr"><div>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)</div><div><br></div><div>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).</div><div><br></div><div>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. </div><div><br></div><div>So two questions do we have something like this already? and if not would this be useful ?</div><div><br></div><div>







<p class=""><span class="">import</span><span class=""> Foundation</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">//MARK:- AngleType</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">protocol</span><span class=""> AngleType: </span><span class="">FloatLiteralConvertible</span><span class="">, </span><span class="">IntegerLiteralConvertible</span><span class=""> {</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">var</span><span class=""> value: </span><span class="">Double</span><span class=""> { </span><span class="">get</span><span class=""> </span><span class="">set</span><span class=""> }</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(</span><span class="">_</span><span class=""> value: </span><span class="">Double</span><span class="">)</span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(</span><span class="">_</span><span class=""> value: </span><span class="">Int</span><span class="">)</span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">&lt;T: </span><span class="">IntegerType</span><span class="">&gt;(integerLiteral value: </span><span class="">T</span><span class="">)</span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">&lt;T: </span><span class="">FloatingPointType</span><span class="">&gt;(floatLiteral value: </span><span class="">T</span><span class="">)</span></p>
<p class=""><span class="">}</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">// Implement FloatLiteralConvertible and IntegerLiteralConvertible</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">extension</span><span class=""> </span><span class="">AngleType</span><span class=""> {</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">&lt;T: </span><span class="">IntegerType</span><span class="">&gt;(integerLiteral value: </span><span class="">T</span><span class="">)</span></p>
<p class=""><span class="">    {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(value)</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">&lt;T: </span><span class="">IntegerType</span><span class="">&gt;(</span><span class="">_</span><span class=""> value: </span><span class="">T</span><span class="">)</span></p>
<p class=""><span class="">    {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(integerLiteral: value)</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">&lt;T: </span><span class="">FloatingPointType</span><span class="">&gt;(floatLiteral value: </span><span class="">T</span><span class="">)</span></p>
<p class=""><span class="">    {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(value)</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">&lt;T: </span><span class="">FloatingPointType</span><span class="">&gt;(</span><span class="">_</span><span class=""> value: </span><span class="">T</span><span class="">)</span></p>
<p class=""><span class="">    {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(floatLiteral: value)</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">}</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">//MARK:- Degree</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">struct</span><span class=""> Degree: </span><span class="">AngleType</span><span class=""> {</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">typealias</span><span class=""> FloatLiteralType = </span><span class="">Double</span></p>
<p class=""><span class="">    </span><span class="">typealias</span><span class=""> IntegerLiteralType = </span><span class="">Int</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">var</span><span class=""> value: </span><span class="">Double</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(</span><span class="">_</span><span class=""> value: </span><span class="">Double</span><span class="">) {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">value</span><span class=""> = value</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(</span><span class="">_</span><span class=""> value: </span><span class="">Int</span><span class="">) {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">value</span><span class=""> = </span><span class="">Double</span><span class="">(value)</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">}</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">protocol</span><span class=""> DegreeConvertiable {</span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(degreeLiteral value: </span><span class="">Degree</span><span class="">)</span></p>
<p class=""><span class="">}</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">extension</span><span class=""> </span><span class="">Degree</span><span class="">: </span><span class="">CustomStringConvertible</span><span class="">, </span><span class="">CustomDebugStringConvertible</span><span class=""> {</span></p>
<p class=""><span class="">    </span><span class="">var</span><span class=""> description: </span><span class="">String</span><span class=""> {</span></p>
<p class=""><span class="">        </span><span class="">return</span><span class=""> </span><span class="">self</span><span class="">.</span><span class="">value</span><span class="">.</span><span class="">description</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">var</span><span class=""> debugDescription: </span><span class="">String</span><span class=""> {</span></p>
<p class=""><span class="">        </span><span class="">return</span><span class=""> </span><span class="">&quot;</span><span class="">\</span><span class="">(</span><span class="">self</span><span class="">.</span><span class="">value</span><span class="">.</span><span class="">description</span><span class="">)°&quot;</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">}</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">extension</span><span class=""> </span><span class="">Degree</span><span class="">: </span><span class="">RadianConvertiable</span><span class=""> {</span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(radianLiteral value: </span><span class="">Radian</span><span class="">) {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">value</span><span class=""> = </span><span class="">Double</span><span class="">(radianLiteral:value) * </span><span class="">180.0</span><span class=""> / </span><span class="">M_PI</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(</span><span class="">_</span><span class=""> value: </span><span class="">Radian</span><span class="">) {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(radianLiteral: value)</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">}</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">//MARK:- Radian</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">struct</span><span class=""> Radian: </span><span class="">AngleType</span><span class=""> {</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">typealias</span><span class=""> FloatLiteralType = </span><span class="">Double</span></p>
<p class=""><span class="">    </span><span class="">typealias</span><span class=""> IntegerLiteralType = </span><span class="">Int</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">var</span><span class=""> value: </span><span class="">Double</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(</span><span class="">_</span><span class=""> value: </span><span class="">Double</span><span class="">) {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">value</span><span class=""> = value</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(</span><span class="">_</span><span class=""> value: </span><span class="">Int</span><span class="">) {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">value</span><span class=""> = </span><span class="">Double</span><span class="">(value)</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">}</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">protocol</span><span class=""> RadianConvertiable {</span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(radianLiteral value: </span><span class="">Radian</span><span class="">)</span></p>
<p class=""><span class="">}</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">extension</span><span class=""> </span><span class="">Radian</span><span class="">: </span><span class="">CustomStringConvertible</span><span class="">, </span><span class="">CustomDebugStringConvertible</span><span class=""> {</span></p>
<p class=""><span class="">    </span><span class="">var</span><span class=""> description: </span><span class="">String</span><span class=""> {</span></p>
<p class=""><span class="">        </span><span class="">return</span><span class=""> </span><span class="">self</span><span class="">.</span><span class="">value</span><span class="">.</span><span class="">description</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">var</span><span class=""> debugDescription: </span><span class="">String</span><span class=""> {</span></p>
<p class=""><span class="">        </span><span class="">return</span><span class=""> </span><span class="">&quot;</span><span class="">\</span><span class="">(</span><span class="">self</span><span class="">.</span><span class="">value</span><span class="">.</span><span class="">description</span><span class="">)</span><span class="">㎭</span><span class="">&quot;</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">}</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">extension</span><span class=""> </span><span class="">Radian</span><span class="">: </span><span class="">DegreeConvertiable</span><span class=""> {</span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(degreeLiteral value: </span><span class="">Degree</span><span class="">) {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">value</span><span class=""> = </span><span class="">Double</span><span class="">(degreeLiteral: value) * </span><span class="">M_PI</span><span class=""> / </span><span class="">180.0</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(</span><span class="">_</span><span class=""> value: </span><span class="">Degree</span><span class="">) {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(degreeLiteral: value)</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">}</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">//MARK:- Adding Conformance To Built In Types</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">extension</span><span class=""> </span><span class="">FloatLiteralType</span><span class="">: </span><span class="">DegreeConvertiable</span><span class="">, </span><span class="">RadianConvertiable</span></p>
<p class=""><span class="">{</span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(degreeLiteral degree: </span><span class="">Degree</span><span class="">) {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">value</span><span class=""> = degree.</span><span class="">value</span><span class="">.</span><span class="">value</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(radianLiteral radian: </span><span class="">Radian</span><span class="">) {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">value</span><span class=""> = radian.</span><span class="">value</span><span class="">.</span><span class="">value</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">}</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">extension</span><span class=""> </span><span class="">CGFloat</span><span class="">: </span><span class="">DegreeConvertiable</span><span class="">, </span><span class="">RadianConvertiable</span></p>
<p class=""><span class="">{</span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(degreeLiteral degree: </span><span class="">Degree</span><span class="">) {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(degree.</span><span class="">value</span><span class="">)</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(radianLiteral radian: </span><span class="">Radian</span><span class="">) {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(radian.</span><span class="">value</span><span class="">)</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(</span><span class="">_</span><span class=""> degree: </span><span class="">Degree</span><span class="">) {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(degreeLiteral: degree)</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(</span><span class="">_</span><span class=""> radian: </span><span class="">Radian</span><span class="">) {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(radianLiteral: radian)</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">}</span></p></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div><span style="font-size:16px;line-height:19.2px"></span><span style="font-size:12.8px"> Wizard</span><br></div><div><a href="mailto:james@supmenow.com" target="_blank">james@supmenow.com</a></div><div>+44 7523 279 698</div></div></div></div></div></div>
</div>