Numeric literals have a polymorphic type:
*Main> :t 3 3 :: (Num t) => t
But if I bind a variable to such a literal, the polymorphism is lost:
x = 3 ... *Main> :t x x :: Integer
If I define a function, on the other hand, it is of course polymorphic:
f x = 3 ... *Main> :t f f :: (Num t1) => t -> t1
I could provide a type signature to ensure the x
remains polymorphic:
x :: Num a => a x = 3 ... *Main> :t x x :: (Num a) => a
But why is this necessary? Why isn't the polymorphic type inferred?
A polymorphic value-type for C++ The class template, polymorphic_value , confers value-like semantics on a free-store allocated object. A polymorphic_value<T> may hold an object of a class publicly derived from T, and copying the polymorphic_value will copy the object of the derived type.
Type inference is the process by which Haskell 'guesses' the types for variables and functions, without you needing to specify these types explicitly. Many functional languages feature type inference. There is lots of theory behind type inference — Hindley-Milner type systems and Unification.
It's the monomorphism restriction which says that all values, which are defined without parameters and don't have an explicit type annotation, should have a monomorphic type. This restriction can be disabled in ghc and ghci using -XNoMonomorphismRestriction
.
The reason for the restriction is that without this restriction long_calculation 42
would be evaluated twice, while most people would probably expect/want it to only be evaluated once:
longCalculation :: Num a => a -> a longCalculation = ... x = longCalculation 42 main = print $ x + x
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