The question is:
Give a type declaration of
(f True) (f 1)
such that it is well-typed or explain why it cannot exist.
Kindly please help me as I am unable to understand how to define type declaration. Thank you.
Here is how I would infer the type of f
from your expression. Note that I'm not presenting how GHC works but how my "brain type checker" works.
f True
is applied to a value, which means that the f
on the left has type f True :: a -> b
, so f :: Bool -> a -> b
.
On the right, we have f 1
, which means that on the right f :: (Num a) => a -> b
, this is when my internal type checker starts to complain, because from the application of f
on the left, I see that f
can be applied to Bool
, and on the right that it can be applied to a number, but Bool
is not an instance of the Num
class.
However this still type checks if there is no constraint on the first argument, so we have f :: a -> b
and… we can't really say anything else I think. (Because b
can be any type, it is perfectly possible that b
is actually a c -> d
, so we can obtain a new function from applying f
partially.)
Note though that even if this type checks (you can check it in GHCi), it is very unlikely that f
as a meaningful definition, in fact the only function it can represent that is not undefined
is const
I think (but correct if I'm wrong). You can say that because there is no constraint on the type of the first argument which is rather strange…
According to your comment f :: a -> b -> Bool
(I was trying to have the most general type possible from the information given by the expression you typed, this is my result is a bit more general.)
There is only one way to define such a function without using undefined
, it has to be a function that discards both its argument and give a constant. Because there is no way f
can be defined for any type immaginable. So the definition of f
is something like:
f _ _ = True
When you apply f True
to f 1
, you apply f True :: b -> Bool
to a function f 1 :: b -> Bool
, this is well typed because b
is a type variable, it can be anything, in particular it is perfectly fine for b
to be a c -> Bool
, and in that case, the type of f True
is in fact f True :: (c -> Bool) -> Bool
. Is it clearer?
If you have the body of f, you can type ":tf" in GHCI (the haskell interpreter) to get its type.
If all you know about f is that (f True) (f 1) compiles, then f could be any constant function of 2 variables, like \\xy -> 2 :: a -> b -> Int
, or \\xy = "foo" :: a -> b -> String
or even \\xy -> readFile "any.txt" :: a -> b -> IO (String)
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.