Reputation: 15917
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
Upvotes: 5
Views: 614
Reputation: 116174
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.
Upvotes: 6