# Monad in Scala

`class Monad M whereret :: a -> M abind :: M a -> (b -> M b) -> M b`

`trait Monad[M[_]] {def ret[A](a: A) : M[A]def bind[A, B](fa: M[A], f: A => M[B]) : M[B]}`

`data State s a = State { runState:: s -> (s, a)}`

`instance Monad (State s) whereret a = State (\s –> (s, a))bind (State fa) f = State \$ \s ->let (s0, a0) = fa s(State fb) = f a0in fb s0`

`case class State[S, A](runState : S => (S, A))`

`object Monad {def apply[M[_]](implicit m : Monad[M]) : Monad[M] = m}`

`object StateMonad {implicit def stateToMonad[S] = new Monad[({type M[a] = State[S, a]})#M] {def ret[A](a: A) = new State[S, A](s => (s, a))def bind[A, B](a: State[S, A], f: A => State[S, B]) = new State((s: S) => {val State(f0) = aval (s0, a0) = f0(s)val State(f1) = f(a0)f1(s0)})}}`

scala只支持一个参数的量化，但是可以通过其他方法来完成柯瑞化。

`trait SM[S] {type M[a] = State[S, a]}`

({type M[a] = State[S, a]})#M == SM[S]#M

‘#’被用来访问内部类型别名。{…}其实就是一个匿名的类型，不过通常我们用来它来做structural typing。

`import StateMonad._def main {val s = Monad[SM[Int]#M].ret(0)Monad[SM[Int]#M].bind(s, (a:Int) => s)}`