title: How do you define your own state monad using scalaz?
body: <p>So I'm trying to define my own state monad by extending the <code>Monad</code> trait in scalaz. I know I'm reinventing the wheel, but I'm trying to learn more about scala and scalaz. My code is as follows:</p>
  
  <pre><code>package pure
  import scalaz._, Scalaz._
  
  object StateUtil {
    sealed trait State[S, A] { self =&gt;
      def unit[A](a : A) : State[S, A] = StateM(s =&gt; (a, s))
      def runState(s : S) : (A, S) 
      def flatMap[B](f : A =&gt; State[S, B]) : State[S, B] = {
          val stateFun = (s : S) =&gt; {
            val (v, ss) = self.runState(s)
            f(v).runState(ss)
          }
          StateM(stateFun)
      }
  
      def map[B](f : A =&gt; B) : State[S, B] = flatMap(f andThen (unit _))
    }
  
    case class StateM[S, A](run : S =&gt; (A, S)) extends State[S, A] {
      def runState(s : S) : (A, S) = run(s)
    }
  
    class StateMonad[S]() extends Monad[({type St[A] = State[S, A]})#St] {
      def point[A](a : =&gt; A) : State[S, A] = StateM(s =&gt; (a, s))
      def bind[A, B](prev : State[S, A])(f : A =&gt; State[S, B]) : State[S, B] = prev flatMap f
      def apply[A](a : =&gt; A) : State[S, A] = point(a)
    }
  
    def put[S](s : S) : State[S, Unit] = StateM(_ =&gt; ((), s))
  
    def get[S]: State[S, S] = StateM(s =&gt; (s, s))
  
  
  }
  </code></pre>
  
  <p>I'm trying to achieve the same behavior as that of the haskell function called <code>stackyStack</code>(the code is in the comment below). The problem is that the <code>get</code> method returns something of type <code>State[S, S]</code>, and I cannot use the scalaz's <code>&gt;&gt;=</code> operator. But I've no idea how to make that work. </p>
  
  <p>And I'm not even sure if this is how you define your own monads using scalaz. And if I want to replicate the <code>do</code> syntax in scala, what else am I missing?</p>
  
  <pre><code>object main {
    import pure.StateUtil._
  
    /*
     *  stackyStack :: State Stack ()  
          stackyStack = do  
            stackNow &lt;- get  
            if stackNow == [1,2,3]  
              then put [8,3,1]  
              else put [9,2,1]  
     */
     type Stack = List[Int]
     def stacky : State[Stack, Unit] = {
       // won't compile, because get returns something of type State[S, S],            
       // and the bind operator is not a memeber of the State trait I defined
       get &gt;&gt;=
     }
  
  
  }
  </code></pre>