What makes the type of this function `Integer`

dodgy x y = x + y * 10

oneIsOne = dodgy 1

dodgy is a function that has 2 params of type Num. I get that 10 is polymorphic at this point so can be different types of numbers and therefore Num instead of something more specific.

oneIsOne is a function that has one param. According to :t its type is oneIsOne:: Integer -> Integer. I don’t see why this isn’t sitll Num i.e., Num a => a -> a. What is forcing it to be an Integer?

Monomorphism restriction.

λ> :set -XNoMonomorphismRestriction
λ> dodgy x y = x + y * 10
λ> oneIsOne = dodgy 1
λ> :t dodgy
dodgy :: Num a => a -> a -> a
λ> :t oneIsOne
oneIsOne :: Num a => a -> a

After all these years, I still have to understand what Monomorphism restriction buys us (maybe some faster type inference?), but in any case you can turn it off or just write the polymorphic signature in full.

λ> :{
Prelude| dodgy x y = x + y * 10
Prelude| oneIsOne :: Num a => a -> a
Prelude| oneIsOne = dodgy 1
Prelude| :}
λ> :t oneIsOne

oneIsOne :: Num a => a -> a

The “monomorphism restriction” is a counter-intuitive rule in Haskell type inference.

:upside_down_face:

Thanks!

1 Like