<div dir="ltr"><div class="markdown-here-wrapper" style=""><p style="margin:0px 0px 1.2em!important">What about taking a mathematical approach to numbers?</p>
<pre style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important">protocol Group : Equatable {
static var zero: Self { get }
static func + (Self, Self) -> Self
static func += (inout Self, Self)
static func - (Self, Self) -> Self
static func -= (inout Self, Self)
static prefix func - (Self) -> Self
}
protocol Ring : Group {
static var one: Self { get }
static func * (Self, Self) -> Self
static func *= (inout Self, Self)
func tryDivide(by: Self) -> Self?
func tryInvert() -> Self?
}
protocol Field : Ring {
static func / (Self, Self) -> Self
static func /= (inout Self, Self)
var inverted: Self { get }
}
protocol VectorSpace : Group {
associatedtype Scalar : Field
static func * (Self, Scalar) -> Self
static func *= (inout Self, Scalar) -> Self
static func / (Self, Scalar) -> Self
static func /= (inout Self, Scalar) -> Self
static func * (Scalar, Self) -> Self
}
</code></pre><p style="margin:0px 0px 1.2em!important">Detalization of mathematical terminology will be determined by what kind of types we have in the standard library. Integer types are rings (except for overflow), floating-point types are fields (except for precision), point types are linear spaces, so I thought the abstractions above are the bare minimum.</p>
<p style="margin:0px 0px 1.2em!important">Unfortunately, Swift doesn’t have rename operations for protocol requirements, so we can’t express groups that use operations other than <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">+</code> and <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">-</code>. What we can do is to include an adapter to wrap current instance in an additive group interface:</p>
<pre style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important">struct MultiplicativeGroupAdapter<T: Field> : Group {
// ...
}
extension Field {
var multiplicativeGroup: MultiplicativeGroupAdapter<Self>
}
</code></pre><div title="MDH:V2hhdCBhYm91dCB0YWtpbmcgYSBtYXRoZW1hdGljYWwgYXBwcm9hY2ggdG8gbnVtYmVycz88ZGl2
Pjxicj48L2Rpdj48ZGl2PmBgYDwvZGl2PjxkaXY+cHJvdG9jb2wgR3JvdXAgOiBFcXVhdGFibGUg
ezwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyBzdGF0aWMgdmFyIHplcm86IFNlbGYgeyBnZXQgfTwv
ZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyBzdGF0aWMmbmJzcDtmdW5jICsgKFNlbGYsIFNlbGYpIC0m
Z3Q7IFNlbGY8L2Rpdj7CoCDCoCBzdGF0aWMgZnVuYyArPSAoaW5vdXQgU2VsZiwgU2VsZik8ZGl2
PiZuYnNwOyAmbmJzcDsgc3RhdGljJm5ic3A7ZnVuYyAtIChTZWxmLCBTZWxmKSAtJmd0OyBTZWxm
PC9kaXY+wqAgwqAgc3RhdGljIGZ1bmMgLT0gKGlub3V0IFNlbGYsIFNlbGYpPGRpdj4mbmJzcDsg
Jm5ic3A7IHN0YXRpYyBwcmVmaXggZnVuYyAtIChTZWxmKSAtJmd0OyBTZWxmPC9kaXY+PGRpdj59
PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5wcm90b2NvbCBSaW5nIDogR3JvdXAgezwvZGl2Pjxk
aXY+Jm5ic3A7ICZuYnNwOyBzdGF0aWMgdmFyIG9uZTogU2VsZiB7IGdldCB9PC9kaXY+PGRpdj4m
bmJzcDsgJm5ic3A7IHN0YXRpYyZuYnNwO2Z1bmMgKiAoU2VsZiwgU2VsZikgLSZndDsgU2VsZjwv
ZGl2PsKgIMKgIHN0YXRpYyBmdW5jICo9IChpbm91dCBTZWxmLCBTZWxmKTxkaXY+Jm5ic3A7ICZu
YnNwOyBmdW5jIHRyeURpdmlkZShieTogU2VsZikgLSZndDsgU2VsZj88L2Rpdj48ZGl2PiZuYnNw
OyAmbmJzcDsgZnVuYyB0cnlJbnZlcnQoKSAtJmd0OyBTZWxmPzwvZGl2PjxkaXY+fTwvZGl2Pjxk
aXY+PGJyPjwvZGl2PjxkaXY+cHJvdG9jb2wgRmllbGQgOiBSaW5nIHs8L2Rpdj48ZGl2PiZuYnNw
OyAmbmJzcDsgc3RhdGljIGZ1bmMgLyAoU2VsZiwgU2VsZikgLSZndDsgU2VsZjwvZGl2PjxkaXY+
Jm5ic3A7ICZuYnNwOyBzdGF0aWMgZnVuYyAvPSAoaW5vdXQgU2VsZiwgU2VsZik8L2Rpdj48ZGl2
PiZuYnNwOyAmbmJzcDsgdmFyIGludmVydGVkOiBTZWxmIHsgZ2V0IH08L2Rpdj48ZGl2Pn08L2Rp
dj48ZGl2Pjxicj48L2Rpdj48ZGl2PnByb3RvY29sIFZlY3RvclNwYWNlIDogR3JvdXAgezwvZGl2
PjxkaXY+Jm5ic3A7ICZuYnNwOyBhc3NvY2lhdGVkdHlwZSBTY2FsYXIgOiBGaWVsZDwvZGl2Pjxk
aXY+Jm5ic3A7ICZuYnNwOyBzdGF0aWMgZnVuYyAqIChTZWxmLCBTY2FsYXIpIC0mZ3Q7IFNlbGY8
L2Rpdj7CoCDCoCBzdGF0aWMgZnVuYyAqPSAoaW5vdXQgU2VsZiwgU2NhbGFyKSAtJmd0OyBTZWxm
PGRpdj4mbmJzcDsgJm5ic3A7IHN0YXRpYyBmdW5jIC8gKFNlbGYsIFNjYWxhcikgLSZndDsgU2Vs
ZjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyBzdGF0aWMgZnVuYyAvPSAoaW5vdXQgU2VsZiwgU2Nh
bGFyKSAtJmd0OyBTZWxmPC9kaXY+wqAgwqAgc3RhdGljIGZ1bmMgKiAoU2NhbGFyLCBTZWxmKSAt
Jmd0OyBTZWxmPGRpdj59PC9kaXY+PGRpdj5gYGA8L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PkRl
dGFsaXphdGlvbiBvZiBtYXRoZW1hdGljYWwgdGVybWlub2xvZ3kgd2lsbCBiZSBkZXRlcm1pbmVk
IGJ5IHdoYXQga2luZCBvZiB0eXBlcyB3ZSBoYXZlIGluIHRoZSBzdGFuZGFyZCBsaWJyYXJ5LiBJ
bnRlZ2VyIHR5cGVzIGFyZSByaW5ncyAoZXhjZXB0IGZvciBvdmVyZmxvdyksIGZsb2F0aW5nLXBv
aW50IHR5cGVzIGFyZSBmaWVsZHMgKGV4Y2VwdCBmb3IgcHJlY2lzaW9uKSwgcG9pbnQgdHlwZXMg
YXJlIGxpbmVhciBzcGFjZXMsIHNvIEkgdGhvdWdodCB0aGUgYWJzdHJhY3Rpb25zIGFib3ZlIGFy
ZSB0aGUgYmFyZSBtaW5pbXVtLjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+VW5mb3J0dW5hdGVs
eSwgU3dpZnQgZG9lc24ndCBoYXZlIHJlbmFtZSBvcGVyYXRpb25zIGZvciBwcm90b2NvbCByZXF1
aXJlbWVudHMsIHNvIHdlIGNhbid0IGV4cHJlc3MgZ3JvdXBzIHRoYXQgdXNlIG9wZXJhdGlvbnMg
b3RoZXIgdGhhbiBgK2AgYW5kIGAtYC4gV2hhdCB3ZSBjYW4gZG8gaXMgdG8gaW5jbHVkZSBhbiBh
ZGFwdGVyIHRvIHdyYXAgY3VycmVudCBpbnN0YW5jZSBpbiBhbiBhZGRpdGl2ZSBncm91cCBpbnRl
cmZhY2U6PGJyPjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+YGBgPC9kaXY+PGRpdj5zdHJ1Y3Qg
TXVsdGlwbGljYXRpdmVHcm91cEFkYXB0ZXImbHQ7VDogRmllbGQmZ3Q7IDogR3JvdXAgezwvZGl2
PjxkaXY+Jm5ic3A7ICZuYnNwOyAvLyAuLi48L2Rpdj48ZGl2Pn08L2Rpdj48ZGl2Pjxicj48L2Rp
dj48ZGl2PmV4dGVuc2lvbiBGaWVsZCB7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7IHZhciBtdWx0
aXBsaWNhdGl2ZUdyb3VwOiBNdWx0aXBsaWNhdGl2ZUdyb3VwQWRhcHRlciZsdDtTZWxmJmd0Ozwv
ZGl2PjxkaXY+fTwvZGl2PjxkaXY+YGBgPC9kaXY+" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0"></div></div></div>