Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get put and state in MonadState

Tags:

haskell

I looked at the MonadState source code, I don't understand why these 3 functions won't get into dead loop? How does this get evaluated?

class Monad m => MonadState s m | m -> s where
    -- | Return the state from the internals of the monad.
    get :: m s
    get = state (\s -> (s, s))

    -- | Replace the state inside the monad.
    put :: s -> m ()
    put s = state (\_ -> ((), s))

    -- | Embed a simple state action into the monad.
    state :: (s -> (a, s)) -> m a
    state f = do
      s <- get
      let ~(a, s') = f s
      put s'
      return a
like image 277
Sawyer Avatar asked Apr 18 '14 07:04

Sawyer


People also ask

What is the difference between get and put in a monad?

Here's the definition of get and put from Control.Monad.State.Class: -- | Return the state from the internals of the monad. get :: m s get = state (\s -> (s, s)) -- | Replace the state inside the monad. put :: s -> m () put s = state (\_ -> ( (), s)) So "get" just returns a State with a function inside of it.

How do you use state monad?

State monad code looks as if the state were a global mutable variable. You access it using get with no arguments, and you modify it by calling put that returns no value. So what have we gained in comparison to C? We might not see the hidden effects, but the compiler does. It desugars every do block and type-checks it.

What is MonadState in Java?

Whereas above we were discussing State, a concrete data type, MonadState is a new typeclass for types that are monads and for which we can define get and put operations. The class allows for a variety of Monad Transformer “stacks” that use state-passing to share a common interface for the basic state operations.

What is the Monad instance declaration for state?

The Monad instance declaration for State looks something like this: instance Monad (State s) where return x = state (\st -> (x, st)) act >>= k = state $ \st -> let (x, st') = runState act st in runState (k x) st' Notice that State s is not a type but a type constructor: it needs one more type variable to become a type.


1 Answers

The definitions of get,put,state in the class declaration are the default implementations, which are meant to be overridden in actual instances of the class. In this way, the dead loop is broken: if an instance defines only state, then get and put are defined in terms of it using the default implementation in the class. Similarly, if an instance defines get and put, then state is defaulted.

For instance, the Eq type class might have been defined as follows:

class Eq a where
    (==) :: a -> a -> Bool
    x == y = not (x /= y)
    (/=) :: a -> a -> Bool
    x /= y = not (x == y)

instance Eq Bool where
    True  == True  = True
    False == False = True
    _     == _     = False
    -- the (/=) operator is automatically derived
instance Eq () where
    () /= () = False
    -- the (==) operator is automatically derived

It is indeed common to have default self-referring implementations which evaluate to bottom unless something is redefined in the instances.

like image 181
chi Avatar answered Oct 06 '22 10:10

chi