Why types for pure (.) and const (.) differs?

hi guys, I don’t understand why types are different for pure (.) and const (.) if they are the same

Applicative instance for function is

instance Applicative ((->) r) where
  pure :: a -> (r -> a)
  -- or --
  pure :: a -> r -> a
  pure x = \ _ -> x
  -- or --
  pure = const

const implementation is

const :: a -> r -> c
const x _ = x

if we apply (.) to const the type will be

const (.) -- :: r -> (b -> c) -> (a -> b) -> a -> c

but if we apply (.) to pure, the type will be

pure (.) :: Applicative f => f ((b -> c) -> (a -> b) -> a -> c)

why for pure, type is not

pure (.) :: Applicative f => f (r -> (b -> c) -> (a -> b) -> a -> c)

is that because r is already partially applied or what?
can you help me to understand? probably I missed subtle thing

pure (.) is not exactly the same as const (.), it is strictly more general (note that this doesn’t always mean “better”). If you look at the type of pure (.) and instantiate the f type parameter to be (->) r then you get the type of const (.):

pure (.) :: Applicative f => f      ((b -> c) -> (a -> b) -> a -> c)
                             (->) r ((b -> c) -> (a -> b) -> a -> c)
                             r -> (b -> c) -> (a -> b) -> a -> c

One remaining thing to check is that there is an instance of Applicative ((->) r) and indeed there is.

4 Likes

:kiss_mark: thank you very much!