使用单位法
Using unit method
我有以下定义和实现:
case class State[S, +A](run: S => (A, S)) {
def map[B](f: A => B): State[S, B] =
flatMap(a => unit(f(a)))
def map2[B, C](sb: State[S, B])(f: (A, B) => C): State[S, C] =
flatMap(a => sb.map(b => f(a, b)))
def flatMap[B](f: A => State[S, B]): State[S, B] = State(s => {
val (a, s1) = run(s)
f(a).run(s1)
})
}
object State {
def unit[S, A](a: A): State[S, A] =
State(s => (a, s))
def get[S]: State[S, S] = State(s => (s, s))
}
trait RNG {
def nextInt: (Int, RNG) // Should generate a random `Int`. We'll later define other functions in terms of `nextInt`.
}
object RNG {
// NB - this was called SimpleRNG in the book text
case class Simple(seed: Long) extends RNG {
def nextInt: (Int, RNG) = {
val newSeed = (seed * 0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFFL // `&` is bitwise AND. We use the current seed to generate a new seed.
val nextRNG = Simple(newSeed) // The next state, which is an `RNG` instance created from the new seed.
val n = (newSeed >>> 16).toInt // `>>>` is right binary shift with zero fill. The value `n` is our new pseudo-random integer.
(n, nextRNG) // The return value is a tuple containing both a pseudo-random integer and the next `RNG` state.
}
}
}
我的问题是,如何在 State
对象上使用 unit
函数?我试过如下:
val s2 = State.unit[RNG, Int](4563)
println(s2.run((x: RNG) => x))
但是编译器抱怨:
Error:(12, 29) type mismatch;
found : state.RNG => state.RNG
required: state.RNG
println(s2.run((x: RNG) => x)._1)
怎么了?
编译错误是由于您调用了s2.run
。 run
是类型为 S => (A, S)
的函数,因此给定状态类型的值 returns 包含结果和新状态的一对。由于 s2
的类型为 State[RNG, Int]
,s2.run
的类型为 RNG => (Int, RNG)
,因此您需要提供 RNG
的值,例如:
s2.run(new RNG.Simple(1))
您正在提供功能 RNG => RNG
。
我有以下定义和实现:
case class State[S, +A](run: S => (A, S)) {
def map[B](f: A => B): State[S, B] =
flatMap(a => unit(f(a)))
def map2[B, C](sb: State[S, B])(f: (A, B) => C): State[S, C] =
flatMap(a => sb.map(b => f(a, b)))
def flatMap[B](f: A => State[S, B]): State[S, B] = State(s => {
val (a, s1) = run(s)
f(a).run(s1)
})
}
object State {
def unit[S, A](a: A): State[S, A] =
State(s => (a, s))
def get[S]: State[S, S] = State(s => (s, s))
}
trait RNG {
def nextInt: (Int, RNG) // Should generate a random `Int`. We'll later define other functions in terms of `nextInt`.
}
object RNG {
// NB - this was called SimpleRNG in the book text
case class Simple(seed: Long) extends RNG {
def nextInt: (Int, RNG) = {
val newSeed = (seed * 0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFFL // `&` is bitwise AND. We use the current seed to generate a new seed.
val nextRNG = Simple(newSeed) // The next state, which is an `RNG` instance created from the new seed.
val n = (newSeed >>> 16).toInt // `>>>` is right binary shift with zero fill. The value `n` is our new pseudo-random integer.
(n, nextRNG) // The return value is a tuple containing both a pseudo-random integer and the next `RNG` state.
}
}
}
我的问题是,如何在 State
对象上使用 unit
函数?我试过如下:
val s2 = State.unit[RNG, Int](4563)
println(s2.run((x: RNG) => x))
但是编译器抱怨:
Error:(12, 29) type mismatch;
found : state.RNG => state.RNG
required: state.RNG
println(s2.run((x: RNG) => x)._1)
怎么了?
编译错误是由于您调用了s2.run
。 run
是类型为 S => (A, S)
的函数,因此给定状态类型的值 returns 包含结果和新状态的一对。由于 s2
的类型为 State[RNG, Int]
,s2.run
的类型为 RNG => (Int, RNG)
,因此您需要提供 RNG
的值,例如:
s2.run(new RNG.Simple(1))
您正在提供功能 RNG => RNG
。