代码在这里:
https://github.com/fpinscala/fpinscala/blob/master/answers/src/main/scala/fpinscala/state/State.scala

  def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = for {
    _ <- sequence(inputs map ((modify[Machine] _) compose update))
    s <- get
  } yield (s.coins, s.candies)

我不明白第二行 s <- get 在这个 for-comprehension 中是如何工作的。

据我所知,第一行创建了一个 State[Machine, List[Unit]] 并且 flatMap 用 _ 丢弃了 List[Unit]。

随后,在第二行中,我不明白 get 是如何应用于第一行中创建的 Machine 的。 Machine 如何传递?

编辑:
感谢 jwvh 和 Markus Appel 的回复,我现在知道 get 是一种没有参数的方法,它返回 State[S, S]

现在我想我明白了,但如果我错了,请纠正我。
首先,我扩展了理解如下。
sequence(inputs map ((modify[Machine] _) compose update))
    .flatMap(_ => get
        .map(s => (s.coins, s.candies))
get.map(s => (s.coins, s.candies) 可以替换为 State(s => (s, s)).map(s => (s.coins, s.candies) 并最终替换为 State(s => (s, (s.coins, s.candies)))
sequence(inputs map ((modify[Machine] _) compose update))
    .flatMap(_ => State(s => (s, (s.coins, s.candies))))

用定义替换外部 sequence(inputs map ((modify[Machine] _) compose update)).flatMap ,我看到
State(s => {
    val (a, s1) = sequence(inputs map ((modify[Machine] _) compose update)).run(s)
    f(a).run(s1)
  })

现在我用 f(a) 的评估代替 _ => State(s => (s, (s.coins, s.candies)))
State(s => {
    val (a, s1) = sequence(inputs map ((modify[Machine] _) compose update)).run(s)
    State(s => (s, (s.coins, s.candies))).run(s1)
  })

本质上, sequence(inputs map ((modify[Machine] _) compose update)) 在执行输入列表后在最终状态下生成 Machine 并生成 State[Machine, List[Unit]] 类型的输出。但是这个 State 内的实际 Machine 没有明确传递。相反,当它通过 flatMap 调用 State(s => (s, (s.coins, s.candies))).run(s1) 时,它​​由 .run(s1) 定义隐式传递。

最佳答案

正如@jwvh 已经指出的那样, getobject State 中定义的一种方法。get -method 既不应用于任何 Machine,也不将 Machine 用作参数,因为该函数具有以下签名:

def get[S]: State[S, S] = State(s => (s, s))

这意味着 get 没有参数,返回类型是 State[S, S]

关于scala - Scala 中的函数式编程练习 6.11。这种理解是如何工作的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58587641/

10-10 05:18