I defined a function as follows in Haskell
func x | x > 0 = 4
| otherwise = error "Non positive number"
Its inferred type is
func :: (Ord a, Num a, Num t) => a -> t
Why can't its type be
func :: (Ord a, Num a) => a -> a
The type func :: (Ord a, Num a) => a -> a means that returned type should match with one you passed in. But since you are returning a constant and it doesn't depend on input, its type can be any type of class Num. Thus, compiler infers func :: (Ord a, Num a, Num t) => a -> t.
The inferred type is correct. Let's see how it gets inferred. We will only look at the returned value first:
func x | … = 4
| … = error "…"
The latter term, error "…" :: a, is unconstrained. However, 4 has the type Num a => a, therefore your function will have type
func :: (Num result) => ????? -> result
Now let's have a look at x:
func x | x > 0 = …
| …
Due to the use of (>) :: Ord a => a -> a- > Bool and 0 :: Num a, x's has to be an instance of both Num and Ord. So from that point of perspective, we have
func :: (Num a, Ord a) => a -> ????
The important part is that 4 and x don't interact. Therefore func has
func :: (Num a, Ord a, Num result) => a -> result
Of course, result and a could be the same type. By the way, as soon as you connect x and 4, the type will get more specific:
func x | x > 0 = 4 + x - x
| …
will have type (Num a, Ord a) => a -> a.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With