Skip to content

Instantly share code, notes, and snippets.

@tLewisII
Last active December 15, 2015 22:30
Show Gist options
  • Save tLewisII/987d7c0f4ecd873b89a7 to your computer and use it in GitHub Desktop.
Save tLewisII/987d7c0f4ecd873b89a7 to your computer and use it in GitHub Desktop.
Basic Writer [String] A Writer monad
//bind
operator infix >>= {
associativity left
}
struct Writer<A> {
let a:A
let s:String[]
init(_ a:A, _ s:String[]) {
self.a = a
self.s = s
}
static func writer(a:A, _ s:String[]) -> Writer<A> {
return Writer(a,s)
}
func runWriter() -> (A, String[]) {
return (a,s)
}
//return
static func wrap(val:A) -> Writer<A> {
return Writer(val, [""])
}
}
func logWriter<A>(w:Writer<A>) {
for x in w.runWriter().1 {
println(x)
}
}
func ==<A:Equatable>(lhs:Writer<A>, rhs:Writer<A>) -> Bool {
return lhs.runWriter().0 == rhs.runWriter().0 && lhs.runWriter().1 == rhs.runWriter().1
}
func >>=<A,B>(w:Writer<A>, f:A -> Writer<B>) -> Writer<B> {
let (val1, log1) = w.runWriter()
let (val2, log2) = f(val1).runWriter()
var temp1 = Array(log1)
for x in log2 {
temp1 += x
}
return Writer.writer(val2, temp1)
}
let one = 1
let b = Writer(one, ["should be \(one)"])
let a = b >>= { (val:Int) in Writer.writer(val + 2, ["should be \(val + 2)"])} >>= {(val:Int) in Writer.writer(val + 2, ["should be \(val + 2)"])}
let mapped = [1,2,3,4].map {Writer($0, ["val should be \($0)"])}
let reduced = [1,2,3,4].reduce(Writer(0, ["Should be 0"])) {
(let start, let reduce) -> Writer<Int> in
return start >>= {Writer.writer($0 + reduce, ["should be \($0 + reduce)"])}
}
logWriter(reduced)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment