州Monad可以用于自我修改功能吗?

时间:2014-12-08 22:43:17

标签: scala functional-programming state-monad

我想以功能性方式表示自我修改功能,这使我考虑了状态monad。来自“Scala中的函数编程”一书中的版本本质上是函数S =>的案例类包装器。 (R,S)其中S是状态,R是结果。例如,它适用于此随机数生成器,如下所示:

trait RNG {
    def nextInt : Int
}

case State[S,R]( run : S => (R,S) ) { /* other details omitted */ }

type Rand[R] = State[RNG,R] // `random generator of R'

所以这一切都很好,因为我们不需要RNG('state'部分)以外的参数来返回R('结果'部分)。

对于自我修改功能,希望使用状态monad来提出以下更具语法结构的版本:

trait Fn[A,R] {
   def apply(a: A): (R,Fn[A,R])
}

理想情况下,这可以通过mapflatMap方法完成(然后可以通过Scala自动对其进行加糖处理)。

然而,与Rand示例不同,Fn采用类型为A的参数。

使用状态monad,这种事情仍然可以代表吗? 如果没有,它仍然可以表示为monand,如果是这样,那么如何将map或flatMap中的任何一个视为基本*?

*我提到了最后一点,因为FPiS monad特性似乎将map视为基本操作。

1 个答案:

答案 0 :(得分:3)

这应该没事;显而易见的方法将起作用:

def applyState[A, R](a: A) = State(fn: Fn[A, R] => fn.apply(a))

val composedState = for {
  firstResult <- applyState[Int, Thingy](2)
  secondResult <- applyState[Int, Thingy](4)
} yield secondResult

composedState.run(new Fn[Int, Thingy]{...})