我需要在 State Monad 中计算与状态中剩余元素一样多的次数
I need to compute as many times as remaining elements in the state in a State Monad
我正在研究这个用 State monad 实现的堆栈示例。它使用 scalaz 中的状态 monad 实现。
示例取自 Eugene Yokota post http://eed3si9n.com/learning-scalaz/State.html
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))
我一直在尝试实现一段代码以功能方式清空堆栈。 stackManip
的定义使用了两次pop
但是如果我希望pop的数量与状态中元素的数量相同(List[Int]
)怎么办?
第一个弹出的问题是 "Why would you need that?" 答案是我正在尝试实现一个非常相似的案例,在该案例中我需要执行 pop 的次数与 statt 中的元素一样多。如果有人可以帮助我处理堆栈示例,那么我就可以实现我的特定案例。
您可以在示例中添加以下 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
如果您想调用 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)
}
我正在研究这个用 State monad 实现的堆栈示例。它使用 scalaz 中的状态 monad 实现。
示例取自 Eugene Yokota post http://eed3si9n.com/learning-scalaz/State.html
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))
我一直在尝试实现一段代码以功能方式清空堆栈。 stackManip
的定义使用了两次pop
但是如果我希望pop的数量与状态中元素的数量相同(List[Int]
)怎么办?
第一个弹出的问题是 "Why would you need that?" 答案是我正在尝试实现一个非常相似的案例,在该案例中我需要执行 pop 的次数与 statt 中的元素一样多。如果有人可以帮助我处理堆栈示例,那么我就可以实现我的特定案例。
您可以在示例中添加以下 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
如果您想调用 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)
}