简体   繁体   中英

Check and find type in Haskell

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM