I\'m helping a friend learn Haskell and he recently created code like this, which type checks and produces a CPU-burning loop at runtime. I\'m completely baffled by this.
There isn't an instance for (->) String
, but there is an instance for (->) e
... and that instance is very, very useful in many situations. For the second question, we must take a look at forever
and the class instance for functions:
instance Monad ((->) e) where
return x = \e -> x
m >>= f = \e -> f (m e) e
forever m = m >> forever m = m >>= \_ -> forever m
Now, what does forever putStrLn
do?
forever putStrLn
= putStrLn >>= \_ -> forever putStrLn
= \e -> (\_ -> forever putStrLn) (putStrLn e) e
= \e -> (forever putStrLn) e
= forever putStrLn
...it's just a pure infinite loop, basically identical to loop = loop
.
To get some intuition for what's going on with the reader monad (as it is known), take a look at the documentation, the All About Monads section on Reader, and there are some hints sprinkled throughout the Typeclassopedia which might help.
Control.Applicative
imports Control.Monad.Instances
, and therefore re-exports the instances from Control.Monad.Instances
. This includes Functor
and Monad
instances for ((->) r)
.