Skip to content

Instantly share code, notes, and snippets.

@tLewisII
Created June 25, 2014 03:49
Show Gist options
  • Save tLewisII/c44a70a560488edea29a to your computer and use it in GitHub Desktop.
Save tLewisII/c44a70a560488edea29a to your computer and use it in GitHub Desktop.
Monoid with Dual and Writer
operator infix <> {
associativity left
}
protocol Monoid {
typealias M
func mempty() -> M
func mappend(a:M) -> M
}
struct Dual<A:Monoid where A.M == A> :Monoid, Printable, DebugPrintable {
typealias M = Dual
let m:A
func mempty() -> M {
return Dual(m.mempty())
}
func mappend(a: M) -> M {
return Dual(a.m.mappend(m))
}
init(_ aa:A) {
m = aa
}
var debugDescription:String {
return "\(m)"
}
var description:String {
return "\(m)"
}
}
extension String : Monoid {
typealias M = String
func mempty() -> M {
return ""
}
func mappend(a:M) -> M {
return self + a
}
}
extension Array : Monoid {
typealias M = Array
func mempty() -> M {
return []
}
func mappend(a:M) -> M {
var temp = Array(self)
for x in a {
temp += x
}
return Array(temp)
}
}
struct Writer<A, B:Monoid> {
let a:A
let s:B
init(_ a:A, _ s:B) {
self.a = a
self.s = s
}
static func writer(a:A, _ s:B) -> Writer<A, B> {
return Writer(a,s)
}
func runWriter() -> (A, B) {
return (a,s)
}
//return
static func wrap(val:A) -> Writer<A, B> {
return Writer(val, Array<String>() as B)
}
func logWriter() {
println(self.runWriter().1)
}
}
func <><A:Monoid where A.M == A>(lhs:A, rhs:A) -> A {
return lhs.mappend(rhs)
}
func >>=<A, B, C:Monoid where C.M == C>(w:Writer<A,C>, f:A -> Writer<B,C>) -> Writer<B,C> {
let (val1, log1) = w.runWriter()
let (val2, log2) = f(val1).runWriter()
var temp1 = log1 <> log2
return Writer.writer(val2, temp1)
}
let array = [1,2,3,4]
let reduced = array.reduce(Writer(0, Dual(["Should be 0"]))) {
(let start, let reduce) in
return start >>= {Writer.writer($0 + reduce, Dual(["should be \($0 + reduce)"]))}
}
reduced.logWriter()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment