haskell polymorphic function evaluation error

Sawyer

The following code doesn't compile:

foo :: Num a => (a -> a) -> Either Integer Double -> Either Integer Double
foo f x = case x of
  Left i -> Left $ f i
  Right d -> Right $ f 

and give the following error:

Couldn't match type `Integer' with `Double'
Expected type: Either Integer Double
Actual type: Either Integer a
In the expression: Right $ f d
In a case alternative: Right d -> Right $ f d

This is a follow up question to this question, the problem is solved by using RankNTypes:

(forall a. Num a => a -> a)

But the answer didn't say anything. I want to know:

  • what's the root cause of this error? The eventual result would only be one of the case branch, f wouldn't be typed to two types at the same time, the type of f should be checked as long as f :: Num a => (a -> a), either Integer -> Integer or Double -> Double should work, could someone elaborate why this causes an error?

  • Is there any other way to fix the error? Why RankNTypes would fix the error? This strike me like the Monomorphism Restriction error I got the other day, but the enable it doesn't help me fix this, and the explicit type annotation doesn't work either.

Ingo

The root cause is, that with your original definition, a is too general. Consider:

foo :: Num a => (a -> a) -> Either Integer Double -> Either Integer Double
foo f x = case x of
  Left i -> Left $ f i

At this point, the type checker comes in trouble, because the type of Left $ f i must be Either Integer Double, hence the expression f i must be Integer. But you said that the caller may pass any function mapping a numeric type to itself. For example, your type signature permits to pass a Double -> Double function. Clearly, such a function may never result in Integer, hence the application of f is not well typed here.

OTOH, if you use the solution with higher ranked types, you won't be able to pass any function that works on specific types - only functions that work on all numeric types. For example, you could pass negate, but not ((1::Integer)+). This absolutly makes sense, as you also apply the same function to a Double value in the other case alternative.

So, to answer your second question, the higher ranked type solution is the correct one, given your code. You obviously can only want to pass functions like negate if you want to apply it to an Integer and a Double.

Bottom line: With

f :: (a -> a) -> b

you could pass functions like id, tail, reverse, ((1::Int)+). With

f :: (forall a. a -> a) -> b

you could only pass functions with that exact type signature forall a. a->a (modulo type variable renaming) such as id, but none of the others mentioned above.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

haskell polymorphic function evaluation error

From Dev

Haskell function parameter force evaluation

From Dev

Writing a polymorphic Haskell function with ST array

From Dev

How to explicitly instantiate/specialise a polymorphic Haskell function?

From Dev

Haskell polymorphic function Using Either Left Right

From Dev

polymorphism in haskell: the compiler doesn't let my function be polymorphic

From Dev

Haskell polymorphic function to convert between algebraic data types

From Dev

Haskell polymorphic inference in a recursive function/using the input type signature?

From Dev

Haskell Polymorphic Recursion with Composed Maps causes Infinite Type Error

From Dev

Lazy evaluation in Haskell's do notation using the trace function

From Dev

NaN result on large number distance in Haskell, only in function evaluation

From Dev

NaN result on large number distance in Haskell, only in function evaluation

From Dev

List of polymorphic functions in haskell?

From Dev

Matching polymorphic data in Haskell

From Dev

Haskell - Illegal Polymorphic type?

From Dev

haskell polymorphic type functions

From Dev

Polymorphic type aliases in haskell

From Dev

Lazy Evaluation and Strict Evaluation Haskell

From Dev

Function evaluation

From Dev

basic haskell: error with simple function

From Dev

Convert haskell function to prolog error

From Dev

Haskell syntax error in my function

From Dev

Haskell - error in find/replace function

From Dev

Haskell syntax error in my function

From Dev

Convert haskell function to prolog error

From Dev

Evaluation, let and where in Haskell

From Dev

Haskell, lambda calculus for Evaluation

From Dev

Evaluation and space leaks in Haskell

From Dev

Haskell Time Limit on Evaluation

Related Related

  1. 1

    haskell polymorphic function evaluation error

  2. 2

    Haskell function parameter force evaluation

  3. 3

    Writing a polymorphic Haskell function with ST array

  4. 4

    How to explicitly instantiate/specialise a polymorphic Haskell function?

  5. 5

    Haskell polymorphic function Using Either Left Right

  6. 6

    polymorphism in haskell: the compiler doesn't let my function be polymorphic

  7. 7

    Haskell polymorphic function to convert between algebraic data types

  8. 8

    Haskell polymorphic inference in a recursive function/using the input type signature?

  9. 9

    Haskell Polymorphic Recursion with Composed Maps causes Infinite Type Error

  10. 10

    Lazy evaluation in Haskell's do notation using the trace function

  11. 11

    NaN result on large number distance in Haskell, only in function evaluation

  12. 12

    NaN result on large number distance in Haskell, only in function evaluation

  13. 13

    List of polymorphic functions in haskell?

  14. 14

    Matching polymorphic data in Haskell

  15. 15

    Haskell - Illegal Polymorphic type?

  16. 16

    haskell polymorphic type functions

  17. 17

    Polymorphic type aliases in haskell

  18. 18

    Lazy Evaluation and Strict Evaluation Haskell

  19. 19

    Function evaluation

  20. 20

    basic haskell: error with simple function

  21. 21

    Convert haskell function to prolog error

  22. 22

    Haskell syntax error in my function

  23. 23

    Haskell - error in find/replace function

  24. 24

    Haskell syntax error in my function

  25. 25

    Convert haskell function to prolog error

  26. 26

    Evaluation, let and where in Haskell

  27. 27

    Haskell, lambda calculus for Evaluation

  28. 28

    Evaluation and space leaks in Haskell

  29. 29

    Haskell Time Limit on Evaluation

HotTag

Archive