背景
val forExpression
(下面)返回一个StateT
monad,它将一个参数作为一个初始状态,将2和3加到状态,然后将它乘以10。
问题
为什么在这两个函数显示结果后运行此add(2)
实例时,add(3)
和StateT
函数已执行"扔掉"通过将其分配给下划线?
示例
如果您评估的forExpression
开头状态为IntState(1)
,为什么会返回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
答案 0 :(得分:3)
简单的高级解释:StateT
计算具有单独的状态和结果(例如代码中的newState
中的newValue
和IO((newState, newValue))
。 <-
左侧显示的内容是newValue
部分,只有_ <- ...
才会忽略它。对newState
的操纵是隐含的,并且不会被抛弃。
对于低级别,您可以:
将for-comprehension翻译为flatMap
。
扩展StateT
的{{1}}的定义。
查看结果函数中的状态会发生什么。