
어떻게 Monad를 사용해야 하는가?
flatLift, flatLift2ddo(Haskell), for(Scala)var sum = 0
for i in 1...10 {
    sum += i
}
reapply: (Container<T>, U, (U, T) -> U) -> U
func reapply(_ container: [T], _ initial: U, _ transform: (T, U) -> U) -> U {
    var result = initial
    for element in container {
        result = transform(result, element)
    }
    return result
}
reapply([1, 2, 3, 4, 5], 0, {
    $0 + $1
})
repeat(Lisp), foldl(Haskell), reduce(Swift) 등의 이름으로 불리는 함수이다.let opt: T?
let opu: U?
optional.flatLift2d { (t: T, u: U) -> V? in
    // ...
} (opt, opu)
flatLift도 이와 다르지 않다. (T, U) -> V?를 보내는 함수를 정의하여(T?, U?) -> V?로 바꿔주는 연산이 flatLift2d임을 어렵지 않게 생각할 수 있다.let opt: [T] = [3, 7]
let opu: [U] = [2, 4, 8]
Array.flatLift2d { (t: T, u: U) -> [V] in
    List.unit { t*10 + u }
} (opt, opu) // [32, 34, 38, 72, 74, 78]
flatMap과 같은 변종을 제공한다.do {
    t <- opt
    u <- opu
    f(t, u)
}
do를 사용한다.integra {
    y <- [0, 1]
    x <- [0, y]
    pow(x, y)
}
do {
    t <- opt
    unit(true)
}
true가 있는 경우, 없는 경우로 바꿔서 처리하고 있다.
좋은 글이네요. 공유해주셔서 감사합니다.