使用monads

时间:2017-05-18 19:06:18

标签: scala functional-programming monads

我一直在尝试学习Scala中的函数式编程,最后我设法理解了如何使用for comprehension来处理状态:

#!/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)

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

编辑:显然,我的问题不明确。我想使用monad trait运行它,就像这个,我从#34; Scala中的函数编程&#34;中获取:

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 = stateMonad [Int]等实例化来执行计算。

1 个答案:

答案 0 :(得分:2)

在尝试之后,我设法让它发挥作用。所以,我想我最终会回答我自己的问题。解决方案是

# cd /var/www/html/helloapp
# python manage.py runserver
Traceback (most recent call last):
  File "manage.py", line 8, in <module>
    from django.core.management import execute_from_command_line
ImportError: No module named django.core.management

这个想法是让StateMonad类从Monad继承,并包含操作state作为StateMonad类方法的所有函数。正如所指出的,我之前的代码已经可以被认为是monad,但我认为这样做更好。