Skip to content

Instantly share code, notes, and snippets.

@globulon
Created February 11, 2012 21:04
Show Gist options
  • Select an option

  • Save globulon/1804196 to your computer and use it in GitHub Desktop.

Select an option

Save globulon/1804196 to your computer and use it in GitHub Desktop.
First experiment in deriving the state monad from the monad definition
//Check whole project https://github.com/globulon/Scala-Patterns-Experiments
object SM {
case class State[T, S](f: (S) => (T,S)) {
def apply(s: S): (T, S) = f(s)
}
implicit def stateToComprehension[T, S](state: State[T,S]) = new {
implicit val functor = stateFunctor[S]()
val monad = stateMonad[S]()
def map[U](f: T => U) = functor.map(state)(f)
def flatMap[U](f: T => State[U, S]) = monad.flatMap(state)(f)
}
implicit def stateFunctor[S]() = new Functor[({type λ[α] = State[α,S]})#λ] {
def map[T, U](source: State[T, S])(f: T => U): State[U, S] = new State[U, S]((s: S) => {
val (value, state) = source(s)
(f(value), state)
})
}
implicit def stateMonad[S]() = new Monad[({type λ[α] = State[α,S]})#λ]{
def apply[T](data: T) = new State((s: S) => (data, s))
def flatten[T](m: State[State[T, S], S]): State[T, S] = new State[T, S]((s: S) => {
val (mp, sp) = m(s)
mp(sp)
})
}
}
val resultp = for {
_ <- pushP(3)
_ <- pushP(5)
_ <- pushP(7)
_ <- pushP(9)
_ <- popP
} yield ()
println(resultp(List(1))._2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment