The const (++) type in Haskell
I am trying to understand the type of const expression (++)
in Haskell. I know separate types const
and (++)
, and I know that you can leave parameters to return partially applied functions.
If I type :t const (++)
, I get const (++) :: b -> [a] -> [a] -> [a]
. I think I (++)
want two lists (I know, however, that all functions in Haskell are curry functions that actually take only one argument) and returns a list. This list is the first argument to a function const
that expects another argument. So I thought the type would beconst (++) :: [a] -> [a] -> b -> [a].
But for example: const (++) 1 "hello" "you"
returns "helloyou"
. Why is the result returned from the operation const
not the first argument, as defined const
, which is const x _ = x
? Where am I going wrong in my thought process?
source to share
Why is the thing returned from a const operation is not the first argument
It. The first argument const
is (++)
. So the result of the operation const (++) 1
is actually (++)
what is the first argument. So, const (++) 1
- (++)
, which means const (++) 1 "hello" "you"
is (++) "hello" "you"
and this "helloyou"
.
source to share
(++) :: [a] -> [a] -> [a]
≡ ([a] -> [a] -> [a])
const :: c -> b -> c
Now, in const (++)
, you want to give (++)
as an argument const
. The argument const
must be of type c
, so you combine it with the type(++)
c ~ ([a] -> [a] -> [a])
and get a specialized version
const :: ([a] -> [a] -> [a]) -> b -> ([a] -> [a] -> [a])
If this looks confusing, consider a simpler case const 1
. If it 1
has a type Int
, then we must have, c ~ Int
and in this case
const :: Int -> b -> Int
Since function arrows are right-associative, (++)
-specialization can also be written
const :: ([a] -> [a] -> [a]) -> b -> [a] -> [a] -> [a]
Now if you actually apply this to (++)
, you saturate the function argument and end up with
const (++) :: b -> [a] -> [a] -> [a]
source to share