带有函数参数的Scala case类
我正在使用以下代码:带有函数参数的Scala case类,scala,Scala,我正在使用以下代码: case class State[S, +A](run: S => (A, S)) { ... def flatMap[B](f: A => State[S, B]): State[S, B] = State(s => { val (a, s1) = run(s) f(a).run(s1) }) ...
case class State[S, +A](run: S => (A, S)) {
...
def flatMap[B](f: A => State[S, B]): State[S, B] = State(s => {
val (a, s1) = run(s)
f(a).run(s1)
})
...
}
这是对纯功能状态的抽象,摘自本手册第6节run
是一个函数参数,它接受一个状态并发出一个值和新状态的元组
我的问题围绕本节中的语法s=>
:
... B] = State(s => { ...
这似乎是在使用状态
“构造函数”(即应用
)来构建新的状态对象。但是s
代表什么呢?它是否为“匿名”状态,表示任何状态实例?如果是这样,它与本有何不同?或者s是否对应于run
的输入参数,即s
来自:
... (run: S => ....
为什么我要对函数定义使用构造函数呢?请注意,flatMap定义的最后一个符号是)
而不是}
,这将关闭状态
应用构造函数
此场景与标准场景略有不同
case class Person(name: String)
场景,所以我想我会问…您的第二个假设是正确的,
s
对应于run
函数的输入参数,即s
,它表示通过链的实际状态。所以s=>{…}
只是s=>(a,s)
类型的lambda定义。Scala中的lambda和函数是(值),因此您可以将它们作为参数传递到另一个类型(包括一些monad)中
这里,生成新原始状态S
(和新结果A
)的函数被包装(参见操作)到monad状态,该状态作为case类实现。我们需要它来定义monad上的flatMap
操作(请参阅)
为了更清楚地说明作为参数的传递函数,可以将代码重写为:
case class State[S, +A](run: S => (A, S)) {
def flatMap[B](f: A => State[S, B]): State[S, B] = {
def newState(s: S) = {
val (a, s1) = run(s)
f(a).run(s1)
}
State(newState _)
}
}
因此,根据:
是一种类型构造函数,它采用两种普通类型(State[S,+A]
和协变S
)并返回一元类型A
State
函数接受一个普通函数并返回(提升到)单子容器State.apply(run:S=>(A,S))
,因此它是单子的“返回”操作符状态
对应于“bind”操作符State.flatMap[B](f:A=>State[S,B]):State[S,B]
Case类仅用于具有显式的“return”函数(
apply
),而不是使用new
运算符。非常感谢@dk14。现在已经很晚了,所以我明天会好好考虑一下,然后投票表决。有趣的是,我在看哪一个显示了这个确切的情况。在18:40对演示者进行解释时,语法是“lambda,它接受一个S并返回一个SB,提升到状态”。在您问题的示例中,从普通类型提升到monad(“return”运算符)由State.apply(run:S=>(a,S))
表示。顺便说一句,这是一个2012年的视频,现代scalaz不接受s=>(A,s)
内部状态。应用-它只在方法中执行,所以只有一个“返回”方法。