我需要计算状态Monad中状态中剩余元素的次数

时间:2015-10-18 01:53:49

标签: scala functional-programming monads scalaz state-monad

我正在研究使用State monad实现的堆栈示例。它使用scalaz中的状态monad实现。

这个例子取自Eugene Yokota的帖子http://eed3si9n.com/learning-scalaz/State.html

    public void ChangBackColor_Click(object sender, EventArgs e)
    {
        if (ColorDialog.ShowDialog() == DialogResult.OK)
        {
            Form1.ChangeBack(ColorDialog.Color);
        }
    }

我一直试图以功能方式实现一段代码来清空堆栈。 public static void ChangeBack(Color clr) { this.BackColor = clr; } 的定义使用 import scalaz._ import scalaz.Scalaz._ type Stack = List[Int] val pop = State[Stack, Int] { case x :: xs => (xs, x) } def push(a: Int) = State[Stack, Unit] { case xs => (a :: xs, ()) } def stackManip: State[Stack, Int] = for { _ <- push(3) a <- pop b <- pop } yield(b) val res: (Stack, Int) = stackManip(List(5, 8, 2, 1)) 两次,但如果我想要pop的数量与状态中的元素数量(stackManip)相同怎么办?

弹出的第一个问题是&#34;你为什么需要这个?&#34;答案是我试图实现一个非常类似的情况,我需要在statt中执行pop的次数。如果有人可以帮我处理堆栈示例,那么我就能够实现我的特定情况。

2 个答案:

答案 0 :(得分:1)

如果你想像堆栈中的元素一样多次调用pop,你可以这样做:

val emptyStack: State[Stack, Unit] = State.init.flatMap { stack =>
    if(stack.isEmpty) {
        State.state( () )
    } else {
        for {
        _ <- pop
        _ <- emptyStack
        } yield ()
    }
}

编辑:另一种方式,滥用scalaz:

type StackState[X] = State[Stack,X]

val emptyStack: State[Stack, Unit] = State.init.flatMap { stack =>
    Applicative[StackState].replicateM_(stack.length, pop)
}

答案 1 :(得分:0)

您可以在示例中添加以下empty定义:

val empty = State[Stack, List[Int]] {
    case xs => (Nil, xs)
}

然后更改stateManip函数以使用它:

def stackManip: State[Stack, List[Int]] = for {
    _ <- push(3)
    l <- empty
} yield l