Constrained polymorphism: variable parameter vs. function

This is a very simple question. I've just started learning Haskell using several different sources. I am currently unable to decipher them.

The following will naturally look fine.

g :: Num a => a -> a
g x = x + 2
h = g (1.0 :: Double)

      

This example of limited polymorphism makes perfect sense to me when I interpret it like this: as long as the parameter provided g

is of type having an instance Num

, everything is fine.

So, consider the following.

x :: Num a => a

      

If I interpret this as above, I get: x

can take any value of a type that has an instance Num

. However, the following types will not appear.

x :: Num a => a
x = (1.0 :: Double)

      

My question is, what's the difference?

I kind of understand what could happen: the second example x

is defined so that it will evaluate any Num

, and (1.0 :: Double)

not fit.

But my vague idea is far from being fully explained, and I'm looking for a better one.

+3


source to share


1 answer


You should read the type g :: Num a => a -> a

like this:

  • the caller g

    selects the typea

  • the caller must prove that it a

    is a numeric type
  • the caller must provide the value of the type argument a

  • g

    must then respond with a result like a

Therefore, x :: Num a => a

it becomes



  • user x

    selects typea

  • the user must prove that he a

    is a numeric type
  • x

    must then respond with a result like a

So, it is x

not allowed to choose a = Double

, the user x

gets the choice. Think for example. from (x :: Int) + 4

: this will check the type when choosing a=Int

. The implementation x

must be generic, so work with all numeric types.

By the way, note that numeric literals are of the same type 42 :: Num a => a

, so we can use them like Double

, like Int

any other numeric type.

+5


source







All Articles