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?
f is const or some function that discards its result.f :: a -> b -> Bool as an answer because there is no reason the result type is required to be Bool. It could be any type (consider f :: a -> b -> Char; f _ _ = 'a'. That allows the expression to type check as well). You might consider asking your teacher about this one. There might have been a mistake.If you have the body of f, you can type ":t f" 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 \x y -> 2 :: a -> b -> Int, or \x y = "foo" :: a -> b -> String or even \x y -> readFile "any.txt" :: a -> b -> IO (String).
> :t f to work, you'd have to have f defined first. But the OP states they aren't given the definition, only the expression.
fgiven?