【问题标题】:Can the State monad be used for self-modifying functions?State monad 可以用于自修改函数吗?
【发布时间】:2014-12-08 22:43:16
【问题描述】:

我想以一种函数式的方式来表示一个自修改函数,这让我想到了 state 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(“状态”部分)以外的参数来返回 R(“结果”部分)。

对于自修改函数,希望使用 state monad 来提出以下语法糖化程度更高的版本:

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

最好使用mapflatMap 方法来完成(然后可以通过Scala 的for 表示法自动加糖)。

但是,与 Rand 示例不同,Fn 采用 A 类型的参数。

这种事情仍然可以使用 state monad 来表示吗? 如果不是,它仍然可以表示为 monand,如果可以,如何写 map 或 flatMap 中的哪一个被认为是基本的*?

*我提到最后一点是因为 FPiS monad trait 似乎将 map 视为基本操作。

【问题讨论】:

    标签: scala functional-programming state-monad


    【解决方案1】:

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

    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]{...})
    

    【讨论】:

    • 非常感谢 - 当希望在 for 语句的主体中创建 State 实例时,这肯定有效。有没有一个简单而优雅的习语,相当于在 for 之外创建 States,然后反复调用 for 的情况?
    • 重复是什么意思?您可以将
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多