22

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?

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
Tom Crockett
  • 30,818
  • 8
  • 72
  • 90
  • Would it make any difference? (I really don't know, although I suspect not) –  Nov 14 '10 at 20:19
  • 3
    It does make a difference; I want the type to remain as general as possible. – Tom Crockett Nov 14 '10 at 20:22
  • Come again? No matter whether `x` is `Integer` or `Num a => a`, you can pass it to any function which expects a `Num`. Functions have to be generic, values don't. –  Nov 14 '10 at 20:27
  • 4
    @delnan: But you can't pass it to a function that expects an `Int`. – sepp2k Nov 14 '10 at 20:29
  • @sepp2k: Ah, that's the missing piece. Thanks. –  Nov 14 '10 at 20:31

2 Answers2

24

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
dfeuer
  • 48,079
  • 5
  • 63
  • 167
sepp2k
  • 363,768
  • 54
  • 674
  • 675
  • Ah yes, the dreaded monomorphism restriction... I've heard of this but never looked into what it was exactly. Thanks! – Tom Crockett Nov 14 '10 at 20:31
  • If I added explicit type signatures to this, would it still be evaluated twice, with the no monomorphism restriction extension? – Justin L. Nov 06 '13 at 22:53
  • @JustinL If it has a polymorphic type, it will be evaluated twice. If it has a monomorphic type, it won't. The monomorphism restriction only affects whether it will get a monomorphic or polymorphic type without annotations. If you add annotations, the monomorphism restriction makes no difference. – sepp2k Nov 06 '13 at 23:09
  • Why can't it just evaluate and store it for each type? – PyRulez Jun 30 '14 at 01:32
  • @PyRulez, it might, if optimizations are enabled and work in the right way in that case. The specialization pass may take care of that. – dfeuer Jul 19 '16 at 04:27
  • Could you explain why it needs to be evaluated twice? – Praxeolitic Dec 27 '17 at 21:28
  • 1
    @Praxeolitic `x :: T1` and `x :: T2` (where T1 and T2 are different instances of `Num`) are different things (they'd have different types and memory representation and possibly even different values sematically), so you can't just store them as a single value. So `x` needs to be implemented as a function (taking the desired instance as an argument). Theoretically that function could cache its result per instance (so `(x :: T1, x :: T2, x :: T2)` would lead to two calculations instead of threel, but GHC does not do that. – sepp2k Dec 28 '17 at 01:34
19

To expand on sepp2k's answer a bit: if you try to compile the following (or load it into GHCi), you get an error:

import Data.List (sort)
f = head . sort

This is a violation of the monomorphism restriction because we have a class constraint (introduced by sort) but no explicit arguments: we're (somewhat mysteriously) told that we have an Ambiguous type variable in the constraint Ord a.

Your example (let x = 3) has a similarly ambiguous type variable, but it doesn't give the same error, because it's saved by Haskell's "defaulting" rules:

Any monomorphic type variables that remain when type inference for an entire module is complete, are considered ambiguous, and are resolved to particular types using the defaulting rules (Section 4.3.4).

See this answer for more information about the defaulting rules—the important point is that they only work for certain numeric classes, so x = 3 is fine while f = sort isn't.

As a side note: if you'd prefer that x = 3 end up being an Int instead of an Integer, and y = 3.0 be a Rational instead of a Double, you can use a "default declaration" to override the default defaulting rules:

default (Int, Rational)
Community
  • 1
  • 1
Travis Brown
  • 138,631
  • 12
  • 375
  • 680
  • 1
    When I put `f = head . sort` in a file and try to load it, I get an error, but when I type `let f = head . sort` in GHCi I get no error, and the resulting binding has this type: `f :: [()] -> ()`. What's up with that?? – Tom Crockett Nov 15 '10 at 18:41
  • 2
    @pelotom: It's because of GHCi's [extended default rules](http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/interactive-evaluation.html#extended-default-rules). – Travis Brown Nov 15 '10 at 18:52