这在分配给下划线时如何理解构建状态?
How does this for comprehension build state while assigning to underscore?
背景
val forExpression
(下)returns 一个 StateT
monad,它将初始状态作为参数,将 2 和 3 添加到状态,然后将其乘以 10。
问题
为什么add(2)
和add(3)
函数在这个StateT
实例是[=43=时执行] 在这两个函数似乎通过将其分配给下划线来获得结果后 "thrown away"?
示例
如果您评估 forExpression
的起始状态为 IntState(1)
,为什么它 return IntState(60)
而不是 IntState(10)
?
下面有一个最小的代码片段,或者您可以查看完整的源代码on github。
这段代码是在阅读 Alvin Alexander 的 "Functional Programming Simplified" 时遇到的。
case class IntState(i: Int)
def add(i: Int) = StateT[IO, IntState, Int] { oldState =>
val newValue = i + oldState.i
val newState = oldState.copy(i = newValue)
IO((newState, newValue))
}
def multiply(i: Int) = StateT[IO, IntState, Int] { oldState =>
val newValue = i * oldState.i
val newState = oldState.copy(i = newValue)
IO((newState, newValue))
}
val forExpression: StateT[IO, IntState, Int] = for {
_ <- add(2)
_ <- add(3)
x <- multiply(10)
} yield x
简单的高级解释:StateT
计算具有独立的状态和结果(例如,代码中 IO((newState, newValue))
中的 newState
和 newValue
)。出现在<-
左边的是newValue
部分,只有在_ <- ...
中被忽略了。 newState
的操作是隐式的,不会被丢弃。
对于低级,你可以:
将for-comprehension翻译成flatMap
.
扩展StateT
的flatMap
的定义。
看看结果函数中的状态会发生什么。
背景
val forExpression
(下)returns 一个 StateT
monad,它将初始状态作为参数,将 2 和 3 添加到状态,然后将其乘以 10。
问题
为什么add(2)
和add(3)
函数在这个StateT
实例是[=43=时执行] 在这两个函数似乎通过将其分配给下划线来获得结果后 "thrown away"?
示例
如果您评估 forExpression
的起始状态为 IntState(1)
,为什么它 return IntState(60)
而不是 IntState(10)
?
下面有一个最小的代码片段,或者您可以查看完整的源代码on github。
这段代码是在阅读 Alvin Alexander 的 "Functional Programming Simplified" 时遇到的。
case class IntState(i: Int)
def add(i: Int) = StateT[IO, IntState, Int] { oldState =>
val newValue = i + oldState.i
val newState = oldState.copy(i = newValue)
IO((newState, newValue))
}
def multiply(i: Int) = StateT[IO, IntState, Int] { oldState =>
val newValue = i * oldState.i
val newState = oldState.copy(i = newValue)
IO((newState, newValue))
}
val forExpression: StateT[IO, IntState, Int] = for {
_ <- add(2)
_ <- add(3)
x <- multiply(10)
} yield x
简单的高级解释:StateT
计算具有独立的状态和结果(例如,代码中 IO((newState, newValue))
中的 newState
和 newValue
)。出现在<-
左边的是newValue
部分,只有在_ <- ...
中被忽略了。 newState
的操作是隐式的,不会被丢弃。
对于低级,你可以:
将for-comprehension翻译成
flatMap
.扩展
StateT
的flatMap
的定义。看看结果函数中的状态会发生什么。