How to derive the type of fmap (const '2') Just

Hello, for anyone interested, type of fmap (const '2') Just is:

ghci> :t fmap (const '2') Just
fmap (const '2') Just :: a -> Char

And for every input answear will be '2'. Now, I want to know how to derive it. At the beginning I though that Char is just functor, and fmap would just applied (const '2') Just like this:

fmap (const '2') Just $ '3' =
fmap ( (const '2') Just ) 3 =
const '2' (Just 3) =
'2'

or something like this:

fmap (const '2') Just $ '3' =
fmap ( (const '2') Just $ 3) =
-- fmap would do nothing?
(const '2') Just 3 =
'2'

But I think everything I wrote is wrong and just blindly guessing.
My question is, is there better and mechanical method to always correctly derive type? If that have something with lambda calcules or other subject, I’m willing to learn.

1 Like

First we look at the Functor instance for functions:https://hackage.haskell.org/package/base-4.19.0.0/docs/src/GHC.Base.html#line-1098 , which says that β€˜fmap = (.)’, that is, function composition.

The type of (.) is (b β†’ c) β†’ (a β†’ b) β†’ (a β†’ c)

Then we observe that β€˜Just’ is a value constructor, i.e a function β€˜:: a β†’ Maybe a’

We plug the definitions in and get

fmap (const β€˜c’ ) Just =
const β€˜c’ . Just =
(\a β†’ β€˜c’) . Just ::
(a β†’ Char) . (u β†’ Maybe u)

so Maybe u unifies with a and is discarded by the first argument of (const β€˜c’) , and we are left with a function β€˜:: u β†’ Char’, which ignores the argument and will always return β€˜c’.

2 Likes

Thank you for great explanation, now I understand it. I will learn to better use hackage.

hackage and hoogle are your friends! Happy to help :slight_smile:

1 Like