Last active
December 14, 2015 18:39
-
-
Save jhaberstro/9aa326e3762f91abbe8f to your computer and use it in GitHub Desktop.
Swift monoid, num, Sum typeclasses with Int32 instances
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
protocol Monoid { | |
class func mzero() -> Self | |
func mop(y: Self) -> Self | |
} | |
func mconcat<M : Monoid>(t: Array<M>) -> M { | |
return (t.reduce(M.mzero()) { $0.mop($1) }) | |
} | |
protocol Num { | |
class func zero() -> Self | |
func succ() -> Self | |
func add(y: Self) -> Self | |
func multiply(y: Self) -> Self | |
} | |
// When there is only one natural typeclass definition, use extensions. This is the ideal syntax. | |
extension Int32: Num { | |
static func zero() -> Int32 { return 0 } | |
func succ() -> Int32 { return self + 1 } | |
func add(y: Int32) -> Int32 { return self + y } | |
func multiply(y: Int32) -> Int32 { return self * y } | |
} | |
extension String: Monoid { | |
static func mzero() -> String { return "" } | |
func mop(y: String) -> String { return self + y } | |
} | |
// When there is more than one natural typeclass (i.e. Sum and Product), create a wrapper type (à la Haskell) and manually wrap/unwrapp | |
struct Sum<A: Num> : Monoid { | |
let value: A | |
static func mzero() -> Sum { return Sum(value:A.zero()) } | |
func mop(y: Sum)-> Sum { return Sum(value: value.add(y.value)) } | |
} | |
let l : Array<Int32> = [1,2,3] | |
// Using only the Num typeclass to perform summation. | |
// Notice that we | |
func sum<A : Num>(xs: Array<A>) -> A { | |
return xs.reduce(A.zero(), { $0.add($1) }) | |
} | |
println(sum(l)) | |
// Using the Sum typeclass to perform summation | |
println(mconcat(l.map { Sum(value:$0) }).value) | |
// Another use of monoids to perform string concatenation | |
println(mconcat(["Hello", " ", "world!"])) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment