어떻게 Monad를 사용해야 하는가?
flatLift
, flatLift2d
do
(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
가 있는 경우, 없는 경우로 바꿔서 처리하고 있다.
좋은 글이네요. 공유해주셔서 감사합니다.