首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Scala中使用monads进行有状态计算

在Scala中使用monads进行有状态计算
EN

Stack Overflow用户
提问于 2017-05-19 03:06:18
回答 1查看 173关注 0票数 1

我一直在努力学习Scala中的函数式编程,最后我终于理解了如何使用for comprehension来处理state:

代码语言:javascript
复制
#!/usr/bin/env scala

case class State[A,S](run: S => (A,S)) {
    def map[B](f: A => B): State[B,S] =
        State(s => {
            val (a, s1) = run(s)
            (f(a), s1)
        })
    def flatMap[B](f: A => State[B,S]): State[B,S] = 
        State(s => {
            val (a,s1) = run(s)
            f(a).run(s1)
        })
}

val increment = State[Unit,Int] {
    x => ((),x+1)
}

val read = State[Int,Int] {
    x => (x,x)
}

def prog = for {
    _ <- increment
    x <- read
    _ <- increment
    y <- read
} yield (x,y)

val ans = prog.run(0)._1

println(ans)

虽然这运行得很好,但我没有设法使用state monad做类似的事情,它比Option更复杂,因为它需要一个额外的类型。如何使用状态monad执行类似于此代码的操作?

编辑:显然,我的问题不清楚。我想使用一个monad特征来运行它,就像我从"Functional programming in Scala“中获得的那样:

代码语言:javascript
复制
def stateMonad[S] = new Monad[({type lambda[x] = State[S,x]})#lambda] {
    def unit[A](a: => A): State[S,A] = State(s => (a, s))
    def flatMap[A,B](st: State[S,A])(f: A => State[S,B]): State[S,B] =
        st flatMap f
}

然后通过像val M= stateMonadInt这样的东西实例化它来执行计算。

EN

回答 1

Stack Overflow用户

发布于 2017-05-19 04:25:47

在尝试之后,我设法让它正常工作。所以,我想我会回答我自己的问题。解决方案是

代码语言:javascript
复制
trait Monad[M[_]] {
    def unit[A](a: => A): M[A]
    def flatMap[A,B](ma: M[A])(f: A => M[B]): M[B]
}

class StateMonad[S] extends Monad[({type lambda[x] = State[x,S]})#lambda] {
    def unit[A](a: => A): State[A,S] = State(s => (a, s))
    def flatMap[A,B](st: State[A,S])(f: A => State[B,S]): State[B,S] =
        st flatMap f

    def increment: State[Unit,Int] = State(x => ((),x+1))
    def read: State[Int,Int] = State(x => (x,x))
}

val m = new StateMonad[Int]

def prog = for {
    _ <- m.increment
    x <- m.read
    _ <- m.increment
    y <- m.read
} yield (x,y)

其思想是使StateMonad类继承自Monad,并将处理状态的所有函数作为StateMonad类的方法包含在内。正如前面所指出的,我之前的代码可能已经被认为是monad,但我认为这样做更好。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44055973

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档