练习6.8,Chiusano和Bjarnason, Scala中的函数编程,p。 87询问如何为以下特征实现flatMap():
trait RNG {
def nextInt: (Int, RNG)
}
type Rand[+A] = RNG => (A, RNG)
答案密钥提供以下解决方案:
def flatMap[A,B](f: Rand[A])(g: A => Rand[B]): Rand[B] =
rng => {
val (a, r1) = f(rng)
g(a)(r1) // We pass the new state along
}
Stackoverflow为flatMap()/ monad问题提供了很多答案,但没有一个能够回答我关于下一行代码的问题。
我不明白该行的语法
g(a)(r1)
(1)我不明白g(a)(r1)是如何评价的。 (r1)提供了什么句法功能?这条线没有举例说明currying,我不相信,因为g只有一个参数:A。 (2)如果g(a)已经返回Rand [B]类型,那么为什么这条线不会在这里结束? (3)g(a)返回的Rand [B]与第二组括号之间的关系是什么:(r1)? (4)如果flatMap()的这个实现的返回类型是Rand [B],它等于RNG => (A,RNG),如何生成箭头右侧的括号?如果我不得不猜测我会说它们是由评估生成的(r1),但是我不明白这个代码给出了我的问题1到3.
答案 0 :(得分:4)
请记住,我们在新的匿名函数中调用f
和g
,如行所示
rng => { ... }
g
在获得Rand[B]
时会返回A
,因此g(a)
会评估从RNG
到(A, RNG)
的函数。
因此g(a)
会返回一个期望RNG
作为参数的函数,然后我们可以使用类型为r1
的{{1}}调用此函数。
通话结果为RNG
。既然(B, RNG)
签名要求您返回与flatMap
相同的Rand[B]
并且我们在函数内返回RNG => (B, RNG)
,那么它与签名完全匹配。