flatMap() 的状态转换实现
Implementation of flatMap() for State transition
练习 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
}
Whosebug 为 flatMap()/monad 问题提供了很多答案,但是 none 它回答了我关于倒数第二行代码的问题。
我不明白该行的语法
g(a)(r1)
(1) 我不明白 g(a)(r1) 是如何计算的。 (r1) 提供什么句法功能?我不相信该行并没有举例说明柯里化,因为 g 只接受一个参数:A。
(2) 如果 g(a) 已经 return 类型 Rand[B],那么为什么行不在这里结束?
(3) g(a)求出的Rand[B] return和第二组括号:(r1)是什么关系?
(4)如果flatMap()的这个实现的return类型是Rand[B],等于RNG => (A, RNG),箭头右边的括号是怎么生成的?如果我不得不猜测,我会说它们是由评估生成的,(r1),但鉴于我的问题 1 到 3,我并不真正理解这段代码。
请记住,我们在一个新的匿名函数中调用 f
和 g
,如行
所示
rng => { ... }
g
returns a Rand[B]
当给定 A
时,因此 g(a)
计算为从 RNG
到 [=18 的函数=].
所以 g(a)
return 是一个需要 RNG
作为其参数的函数,然后我们可以用我们的 r1
调用它,它的类型是 RNG
.
调用的结果是(B, RNG)
。现在,由于 flatMap
签名希望您 return 一个 Rand[B]
与 RNG => (B, RNG)
相同,而我们在函数中 return (B, RNG)
,它与签名完全匹配。
练习 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
}
Whosebug 为 flatMap()/monad 问题提供了很多答案,但是 none 它回答了我关于倒数第二行代码的问题。
我不明白该行的语法
g(a)(r1)
(1) 我不明白 g(a)(r1) 是如何计算的。 (r1) 提供什么句法功能?我不相信该行并没有举例说明柯里化,因为 g 只接受一个参数:A。 (2) 如果 g(a) 已经 return 类型 Rand[B],那么为什么行不在这里结束? (3) g(a)求出的Rand[B] return和第二组括号:(r1)是什么关系? (4)如果flatMap()的这个实现的return类型是Rand[B],等于RNG => (A, RNG),箭头右边的括号是怎么生成的?如果我不得不猜测,我会说它们是由评估生成的,(r1),但鉴于我的问题 1 到 3,我并不真正理解这段代码。
请记住,我们在一个新的匿名函数中调用 f
和 g
,如行
rng => { ... }
g
returns a Rand[B]
当给定 A
时,因此 g(a)
计算为从 RNG
到 [=18 的函数=].
所以 g(a)
return 是一个需要 RNG
作为其参数的函数,然后我们可以用我们的 r1
调用它,它的类型是 RNG
.
调用的结果是(B, RNG)
。现在,由于 flatMap
签名希望您 return 一个 Rand[B]
与 RNG => (B, RNG)
相同,而我们在函数中 return (B, RNG)
,它与签名完全匹配。