Manipulate State object with scalaz

Hi All,

I am learning scalaz by reading below blog:
http://eed3si9n.com/learning-scalaz/State.html

But i am confused by below sample. There is no input parameter defined in the stackManip method signiture, why we can use it like: stackManip(List(5, 8, 2, 1)) ?? I think I must missed some key point of
StateT[Id, S, A]

import scalaz._
import Scalaz._

type Stack = List[Int]

val pop = State[Stack, Int] {
  case x :: xs => (xs, x)
}

def push(a: Int) = State[Stack, Unit] {
  xs => (a :: xs, ())
}

def stackManip: State[Stack, Int] = for {
  _ <- push(3)
  a <- pop
  b <- pop
} yield(b)

stackManip(List(5, 8, 2, 1))

Thanks for any tips

stackManip is of type State[Stack, Int], which has an apply method. In scala, if you have some type with an apply method, you can omit apply, and make it look like a method call.

stackManip(List(5, 8, 2, 1)) is the same as stackManip.apply(List(5, 8, 2, 1)). Apply is implemented below:

trait StateT[F[+_], S, +A] { self =>
  /** Run and return the final value and state in the context of `F` */
  def apply(initial: S): F[(S, A)]

  /** An alias for `apply` */
  def run(initial: S): F[(S, A)] = apply(initial)

  /** Calls `run` using `Monoid[S].zero` as the initial state */
  def runZero(implicit S: Monoid[S]): F[(S, A)] =
    run(S.zero)
}
1 Like

Hi Martijnhoekstra

Thanks a lot for crystal clear explanation.