16
votes

In Haskell, what does ((->) t) mean in the type signature of instances? For example Functor, Applicative and Monad all have an instance along the lines of:

Functor ((->) r)

I can't find any explanation of what this type signature means and it's highly search engine-resistant.

3
highly search engine-resistant -- not for the SO search engine. See stackoverflow.com/q/5310203/11683GSerg
You're right! I guess I should consider sometimes searching SO directly instead of just relying on Google.drt
You can also search on SymbolHound.Joan Charmant
In case anyone who happens across this question is wondering, a good search term is "reader monad".dfeuer

3 Answers

19
votes

-> is an infix type constructor. You can compare it with : - an infix value constructor for list type. To use : alone we put parentheses around it so it becomes a prefix function application:

(:) a b is the same as a : b

Similarly, (->) a b is the same as a -> b, type of a function from a to b.

(->) a is a partial application of type constructor, and itself a type constructor of kind * -> *.

You can think of it as "a constructor of types of functions from a". E.g. (->) Int is a constructor of types of functions from Int. You can construct full function type by passing another type to it: (->) Int String is the type of functions from Int to String.

instance Functor (->) a is a functor with fmap operation transforming an a -> b function into an a -> c function. You can compare it with a similar instance Functor (Either a) which maps Either a b to Either a c by applying the fmap argument to Right values.

12
votes

We could use lambda functions and infix functions:

(->) a    =    \b ->  (->) a b  --pseudo-Haskell
(->) a    =    \b ->  a -> b    --pseudo-Haskell

so, read instance as:

class Functor f where
   fmap :: (a->b) -> f a -> f b

instance Functor ((->)r) where
   fmap :: (a->b) -> f     a  -> f     b
         = (a->b) -> (->)r a  -> (->)r b   --pseudo-Haskell
         = (a->b) -> (r -> a) -> (r -> b)  --pseudo-Haskell
4
votes

You could see it as the set of types r -> a where r is fixed.

A functor is a type function m, which means that for any type a you have a type m a. Examples are Maybe, [] and (->) r. The latter should perhaps better be written (r ->), but I don't know if that's allowed.