练习13
官方答复是:
def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = for {
_ <- sequence(inputs map (modify[Machine] _ compose update))
s <- get
} yield (s.coins, s.candies)
第二行中第二个占位符的位置确实让我困惑,从我的角度来看,正确答案应该是:
def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = for {
_ <- sequence(inputs map ((modify[Machine] compose update) _))
s <- get
} yield (s.coins, s.candies)
请帮助我理解为什么第一个答案是对的,非常感谢
答案 0 :(得分:2)
modify
是一种已知的方法,因此占位符只是方法的eta expansion,将其转换为Function1
并启用其方法compose
3}}
因此,在modify[Machine]
modify[Machine] compose update
之后没有占位符,有时可能会出现编译错误。但是如果没有,那么在完全表达之后也不需要占位符,因为它保证compose
的结果是Function1
并且可以用作map
的参数
答案 1 :(得分:1)
这里的问题是撰写的工作原理: “compose创建一个组成其他函数f(g(x))的新函数”, f compose g可以翻译为:“执行f后g”
scala> val fComposeG = f _ compose g _
fComposeG: (String) => java.lang.String = <function>
此组合返回另一个接受输入并返回新状态[A,S]的函数。
编译器可以让你做出类似的东西:
val ll = inputs map update
现在ll是 List [Machine =&gt;机器]正是更新功能所需要的。修改后必须使用下划线,否则编译器会警告“缺少参数列表以进行方法修改....”
答案 2 :(得分:0)
modify
是一种方法,我们必须将其转换为能够使用compose
的函数。我们在scala中执行此操作的方法是使用占位符语法或使用eta expansion。
(modify[Machine] _
)相当于(f => modify[Machine](f)
)
另一种写这个的方法是:
def modifyFunction: ((Machine => Machine)) => State[Machine, Unit] = f => modify[Machine](f)
def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = for {
_ <- sequence(inputs map (modifyFunction compose update))
s <- get
} yield (s.coins, s.candies)