Home > front end >  Why is "Int -> Int" not the same as "Int x => x -> x"? In this case the
Why is "Int -> Int" not the same as "Int x => x -> x"? In this case the

Time:01-17

Why aren't these two type definitions equivalent?

Also, why isn't "Num a => a -> a" equivalent to "Num -> Num"? In this case the second example is invalid, correct?

I'm assuming it has to do with Num being a Class and Int being a Type, but I'm not clear on what the difference between a Class and Type is in Haskell and how the difference between them is relevant to what type definitions are allowed and what type definitions are not.

Is there a list of Classes and Types in Haskell somewhere?

CodePudding user response:

No, those are not equivalent. Int x is a kind error. Int has kind Type, and then you're trying to apply it to x which has also kind Type. This is like writing 'f' 'x' on the value level – you're trying to apply the function 'f' to the value 'x' but both actually have type Char. Doesn't work.

By contrast, Num x is fine, because Num has kind Type -> Constraint – so this can be applied to something of kind Type just fine.

ghci> :k Int
Int :: Type
ghci> :k Num
Num :: Type -> Constraint

But the signature

   Num x => x -> x

is not the same as the signature

   Int -> Int

although many functions could be defined with either of those signatures. For example, the following both compile without problem:

quadruple :: Int -> Int
quadruple = (*4)

quadruple' :: Num x => x -> x
quadruple' = (*4)

The difference is that quadruple can only be applied to values of the exact type Int. For example, quadruple 3.14 is a type error, because you're trying to feed a fractional value as the argument, which is incompatible with the expected Int input. Whereas quadruple' 3.14 works just fine, by instantiating the x type-variable to (for example) Double. The result is then also of type Double. In other words, the function then specializes to

quadruple'' :: Double -> Double
quadruple'' = quadruple'
  • Related