scala - 采用单位法

标签 scala functional-programming monads

我有以下定义和实现:

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) 的函数,因此给定状态类型的值,它会返回一个包含结果和新状态的对。由于 s2 的类型为 State[RNG, Int],因此 s2.run 的类型为 RNG => (Int, RNG) 因此您需要提供 RNG 值,例如:

s2.run(new RNG.Simple(1))

您正在提供一个函数RNG => RNG

关于scala - 采用单位法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44157271/

相关文章:

f# - 如何使这个 F# 函数不会导致堆栈溢出

java - 如何在 S3 元数据中存储重音字符?

java - 如何在案例类中重用类参数?

algorithm - 函数式编程中的可变性

clojure - 种植我的 Clojure 树

list - 平面列表和自由单子(monad)

f# - 在计算表达式中为 if..then 构造的 else 分支调用零背后的直觉

scala - 在scala中传递默认参数?

scala - 在 scala 中,在 toMap 之后添加不相关的行时编译错误消失

javascript - 函数式编程是否使用对象数据结构?