In the Functor class definition we have the <$
function defined as:
class Functor f where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
(<$) = fmap . const
The const
function has the definition:
const :: a -> b -> a
const x _ = x
I know that the <$
function is equivalent to:
\x -> fmap (const x)
How does fmap . const
equate to the lambda expression above? My understanding of function composition is that output type of const
should match the input type of fmap
, but the input type of fmap
is the function (a -> b)
not a
which is what the const
function outputs.
The other answer does a good job of addressing the question, "How does fmap . const
equate to the lambda expression above?", so I want to address a different part:
My understanding of function composition is that output type of
const
should match the input type offmap
, but the input type offmap
is the function(a -> b)
nota
which is what theconst
function outputs.
In this answer, I will argue that the output type of const
is indeed a function as needed by fmap
.
Let's rewrite the types of fmap
and const
, using separate type variables in each to avoid confusion:
fmap :: Functor f => (a -> b) -> (f a -> f b)
const :: c -> (d -> c)
Now, one must ask: what is the output type of const
? In your question, you posit that the output type is c
(after correcting for type variable renaming as above). But in fact this is a slight misunderstanding; the true output type is d -> c
!
The output of const
is actually a function. Now, as you say, its output must match the input of fmap
. With our naming above, this means we must choose to satisfy the equation d ~ a
(read: type d
and type a
are the same type) and satisfy c ~ b
. Then we will have:
const :: b -> (a -> b)
fmap :: (a -> b) -> (f a -> f b)
fmap . const :: b -> (f a -> f b)