Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the difference in type-inference over the as-pattern in two similar function definitions?

I have the following two similar function definitions:

left f (Left x) = Left (f x) left _ (Right x) = Right x  left' f (Left x) = Left (f x) left' _ r@(Right _) = r 

When I check the type signatures of the two functions, I am confused by the following types:

ghci> :t left left :: (t -> a) -> Either t b -> Either a b ghci> :t left' left' :: (a -> a) -> Either a b -> Either a b 

I suppose left and left' should be of the same type signature, but the haskell's type inference gives me a suprise.

I can't figure out why the type signatures of left and left' are different. Can anybody give me some information? Thanks!

like image 989
Z-Y.L Avatar asked Mar 30 '19 13:03

Z-Y.L


People also ask

What is the difference between type checking and type inference?

A Type Checker only verifies that the given declarations are consistent with their use. Examples: type checkers for Pascal, C. A Type Inference system generates consistent type declarations from information implicit in the program.

What is a type of inference?

Type inference refers to the automatic detection of the type of an expression in a formal language. These include programming languages and mathematical type systems, but also natural languages in some branches of computer science and linguistics.

What is type inference in programming language?

Type inference is the compile-time process of reconstructing missing type information in a program based on the usage of its variables. ML and Haskell are two languages where this aspect of compilation has enjoyed some popularity, allowing type information to be omitted while static type checking is still performed.

How does OCaml type inference work?

Type inference refers to the process of determining the appropriate types for expressions based on how they are used. For example, in the expression f 3 , OCaml knows that f must be a function, because it is applied to something (not because its name is f !) and that it takes an int as input.


Video Answer


1 Answers

In the second line of left':

left' _ r@(Right _) = r --      ^^^^^^^^^^^   ^ 

Since you use an as-pattern, you require the input type to be equal to the return type, since clearly they're the exact same value. left''s type is then restricted to something of the form a -> b -> b.

This restriction then propogates backwards to in turn restrict the function's type – hopefully you can see how; it's not too difficult.

However, in the second line of left, you construct a new value

left _ (Right x) = Right x --                 ^^^^^^^ 

The type of this new value has not been restricted, and thus the same problem doesn't occur; it can be something of the form a -> b -> c, which is what you want.

For this reason, the type of left' is more restricted than the type of left, which is what causes their types to be unequal.


To illustrate this concept more concretely, I will describe to you more precisely how this restriction propogates backwards.

We know that left''s signature is of the form (a -> b) -> Either a q -> Either b q. However, line 2 dictates that Either a q = Either b q, which means that a = b, so the type now becomes (a -> a) -> Either a q -> Either a q.

like image 148
AJF Avatar answered Sep 21 '22 04:09

AJF