Intrigued by (->) as instances of monad and functor
haskell
Solution
It can be a bit confusing at first, but one important concept to remember is that `(->)` is not a monad or functor, but `(->) r` is. `Monad` and `Functor` types all have the kind `* -> *`, so they only expect one type parameter.
What this means is that `fmap` for `(->) r` looks like
fmap g func = \x -> g (func x)
Which is also known as
fmap g func = g . func
which is just normal function composition! When you `fmap g` over `func`, you change the output type by applying `g` to it. In this case, if `func` has the type `a -> b`, `g` must have a type like `b -> c`.
The `Monad` instance is bit more interesting. It lets you use the result of a function application "before" that application has occurred. What helped me understand was seeing an example like
f :: Double -> (Double,Double)
f = do
x1 <- (2*)
x2 <- (2+)
return (x1, x2)
> f 1.0
(2.0, 3.0)
What this does is apply the implicit argument to `f` to each of the functions on the right hand side of the binds. So if you pass in `1.0` to `f`, it will bind the value `2 * 1.0` to `x1` and binds `2 + 1.0` to `x2`, then returns `(x1, x2)`. It really makes it easy to apply a single argument to many subexpressions. This function is equivalent to
f' x = (2 * x, 2 + x)
Why is this useful? One common use is the `Reader` monad, which is simply a newtype wrapper around `(->) r`. The `Reader` monad makes it easy to apply a static global config across your application. You could write code like
myApp :: Reader Config ()
myApp = do
config <- ask
-- Use config here
return ()
And then you run your application with `runReader myApp initialConfig`. You can easily write actions in the `Reader Config` monad, compose them, chain them together, and all of them have access to the global, readonly config. In addition, there's a companion `ReaderT` monad transformer which allows you to build it into your transformer stack, letting you have very complex applications that have easy access to static configuration.
Problem
I am quite intrigued by `(->)` when I looked up in information about `(->)` in ghci. It says, ``` data (->) a b -- Defined in `GHC.Prim` ``` So far so good, but then it gets very interesting when it says - ``` instance Monad ((->) r) -- Defined in `GHC.Base` instance Functor ((->) r) -- Defined in `GHC.Base` ``` What does this implicate? Why does GHC define it as an instance of a Monad, and Functor for `(->)`?