Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有函数参数的Scala case类_Scala - Fatal编程技术网

带有函数参数的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))
    函数接受一个普通函数并返回(提升到)单子容器
    状态
    ,因此它是单子的“返回”操作符
  • State.flatMap[B](f:A=>State[S,B]):State[S,B]
    对应于“bind”操作符

Case类仅用于具有显式的“return”函数(
apply
),而不是使用
new
运算符。

非常感谢@dk14。现在已经很晚了,所以我明天会好好考虑一下,然后投票表决。有趣的是,我在看哪一个显示了这个确切的情况。在18:40对演示者进行解释时,语法是“lambda,它接受一个S并返回一个SB,提升到状态”。在您问题的示例中,从普通类型提升到monad(“return”运算符)由
State.apply(run:S=>(a,S))
表示。顺便说一句,这是一个2012年的视频,现代scalaz不接受
s=>(A,s)
内部
状态。应用
-它只在方法中执行,所以只有一个“返回”方法。