I am studying this example of a stack implemented with the State monad. It uses the state monad implementation in scalaz.
The example has been taken from 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))
I've been trying to implement a piece of code to empty the stack in a functional fashion. The definition of stackManip
uses pop
two times but what if I want the number of pop to be the same as the number of elements in the state (List[Int]
)?
The very first question to pop up would be "Why would you need that?" The answer is that I'm trying to implement a very similar case in which I need to execute pop as many times as elements in the statt. If someone can help me with the stack example then I'd be able to implement my particular case.
If you want to call pop
as many times as elements in the stack you can do something like this:
val emptyStack: State[Stack, Unit] = State.init.flatMap { stack =>
if(stack.isEmpty) {
State.state( () )
} else {
for {
_ <- pop
_ <- emptyStack
} yield ()
}
}
Edit: Another way, abusing scalaz:
type StackState[X] = State[Stack,X]
val emptyStack: State[Stack, Unit] = State.init.flatMap { stack =>
Applicative[StackState].replicateM_(stack.length, pop)
}