2
votes

I'm learning State Monad, and was told it doesn't exist any more, the first question is why Haskell remove it?

and when I using

import Data.Functor.Identity
import Control.Monad.Trans.State

type State s = StateT s Identity

I get

Ambiguous occurrence ‘State’
    It could refer to
       either ‘Control.Monad.Trans.State.State’
           or ‘Main.State’,

but when I tried :t State, I find nothing. This is self-contradictory, I wonder whether it exists or not?

finally, I write it by my self

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

but I alse need some other function like put, get... where are they.

using :i get, I found MonadState, is this the new implement of State?

1
Yes, the State type constructor doesn't exist anymore. Instead you use the state function which resides in the MonadState type class. For more check Control.Monad.State.LazyRedu
You say that you were told the state monad “doesn’t exist any more”. I think it’s worth pointing out that this isn’t entirely correct. State as a standalone monad doesn’t exist any more, but a State monad still exists; however, it’s defined in terms of another StateT monad instead of being implemented as a separate monad of its own. This new state monad lives in the Control.Monad.Trans.State module, in the transformers library. EDIT: I’ve just noticed you are already aware of Control.Monad.Trans.State — sorry for the redundant comment!bradrn

1 Answers

13
votes

I get Ambiguous occurrence

Really, let's try the code you posted..

cat <<EOF >umi.hs
import Data.Functor.Identity
import Control.Monad.Trans.State

type State s = StateT s Identity
EOF
ghci umi.hs

We get

Ok, one module loaded.

So that's actually fine. I suspect you have more code that tries to use State but it is ambiguous because you have imported a State and do not need to define your own State type.

When I tried :t State, I find nothing. This is self-contradictory

When you try :t State you get more than nothing, you get:

:t State

<interactive>:1:1: error:
    • Data constructor not in scope: State

Read that carefully, it says "Data constructor" not "type" or "type constructor". You can't check the type of a type (:t is short of :type). You can, however, use info:

> :i State
type Control.Monad.Trans.State.State s =
  StateT s Identity :: * -> *
        -- Defined in ‘Control.Monad.Trans.State.Lazy’

type Main.State s = StateT s Identity :: * -> *
        -- Defined at umi.hs:4:5

So you see, your (Mains) type alias is redundant of the type alias you imported from Control.Monad.Trans.State. Solution? Just don't define your type alias.

EDIT: The above was intended to clear up some misunderstandings. Answering your actual questions here.

Where is state monad

There are many State monads defined in Haskell libraries. The most popular one is in Control.Monad.Trans.State from the transformers package which you have already found. There's also a the monadlib version of State, and the entirely different MonadState class (in the mtl package) which is a pair of get and set operations for any monad that has some notion of state.

and how can I use it?

Well you import the module and you can runState stateMonadicOperation initialState:

> runState (mapM (\x -> state $ \s -> (x,s+x)) [1..4])  9
([1,2,3,4],19)

There are a lot of state monad questions you can find here on stackoverflow if you have specific questions.

I wonder whether it exists or not?

This depends on the it in your question. There is a State type constructor but no State data constructor.

using :i get, I found MonadState, is this the new implement of State?

No. State the monad is defined in the tranformers as :

type State s = StateT s Data.Functor.Identity.Identity :: * -> *
newtype StateT s (m :: * -> *) a
  = StateT {runStateT :: s -> m (a, s)}

So there is a transformer with a data constructor and a type alias of the transformer and identity monad.

In contrast, the MonadState is just an abstraction of the ability to get and set values:

class Monad m => MonadState s (m :: * -> *) | m -> s where
  get :: m s
  put :: s -> m ()