Scala: Bad inferred type for Option composed with StateT monad transformer

haskell, monad-transformers, monads, scala, scalaz

Solution

In your example, the call to `get[String]` is calling the `get` method of `StateFunctions`, reproduced here:

def get[S]: State[S, S] = init

Where `State[S, A]` is an alias for `StateT[Id, S, A]` which is an alias for `IndexedStateT[Id, S, S, A]`.

Because you are using `StateT`, you need to call `get` on an instance of `StateTMonadState[S, F]`, or `StateTMonadState[String, Option]` in your case. The working example is:

import scalaz._
import Scalaz._

object StateTest {
  type Pass[A] = StateT[Option, String, A]

  val sm = StateT.stateTMonadState[String, Option]

  def monadTest: Pass[String] =
    for {
      s <- sm.get
    } yield s
}

The `MonadState` instance can also be resolved implicitly via `MonadState[F[_, _], S]` but it is less convenient to use due to the type lambda required. See MonadState.scala and StateT.scala for more info.

Problem

I'm somewhat familiar with Haskell monad transformers, but new to Scalaz (version 7). I made (what I thought was) a straightforward translation from the following Haskell code: ``` import Control.Monad.State type Pass a = StateT String Maybe a monadTest :: Pass String monadTest = do s <- get return s ``` to this Scala code: ``` import scalaz._ import Scalaz._ object StateTest { type Pass[A] = StateT[Option, String, A] def monadTest: Pass[String] = for { s <- get[String] } yield s } ``` The Haskell code compiles. The Scala fails to compile, with the following error: ``` [error] .../StateTest.scala:9: type mismatch; [error] found : scalaz.IndexedStateT[scalaz.Id.Id,String,String,String] [error] required: StateTest.Pass[String] [error] (which expands to) scalaz.IndexedStateT[Option,String,String,String] [error] s <- get[String] [error] ^ ``` First, it seems scalaz implements `StateT` in terms of `IndexedStateT`. Ok. But, it seems that the `get[String]` monadic value is inferred to have type `StateT[Id, String, String]` instead of `StateT[Option, String, String]`. Why? I'm using Scala 2.10.1, scalaz 7.0.0.

Original source