(->)
is often called the “function arrow” or “function type constructor”, and while it does have some special syntax, there’s not that much special about it.
It’s essentially an infix type operator. Give it two types, and it gives you the type of functions between those types. Just like 2 + 3
is syntactic sugar for (+) 2 3
, so is from -> to
syntactic sugar for (->) from to
. You can think of it like Function from to
if the symbols are confusing.
In other words, the instance you mentioned can be read as
instance Monad (Function from) where ...
which makes it clear that we’re talking about functions which take arguments of some arbitrary (but fixed) type. In fact, this monad instance is found in Control.Monad.Instances and it is essentially the same as the Reader monad.
Looking at the source, it’s really quite simple:
instance Monad ((->) r) where
return = const
f >>= k = \ r -> k (f r) r
The trivial values given by return
ignore the argument, and the (>>=)
operator distributes the argument r
to both sides.
It’s also interesting to note that in the corresponding Applicative
instance for functions, pure
and (<*>)
correspond to the K and S combinators of the SKI combinator calculus.
(->)
is also generalized by the Arrow type class. An introduction to arrows can be found here.
Finally, note that the symbol ->
also appears in other more or less unrelated parts of the syntax, including lambda abstractions \x -> ...
, case expressions case ... of x -> ...
, etc. The reverse symbol <-
also occurs in several unrelated contexts. Don’t confuse those with the function arrow.