Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transforming a function to point-free style changes its type

I'm beginning Haskell... I tried to write the following trivial function in two different ways, letting Haskell decide the types, and the type system does something different in each case. What is the explanation for that behavior?

Prelude> let f x = 2 * x
Prelude> let g = (2*)
Prelude> :info f
f :: Num a => a -> a    -- Defined at <interactive>:1:5
Prelude> :info g
g :: Integer -> Integer     -- Defined at <interactive>:1:5

Thanks!

like image 849
Frank Avatar asked May 19 '11 00:05

Frank


2 Answers

This is known as the monomorphism restriction.

Basically, it means that top-level bindings that look like x = are forced to be non-polymorphic, unless you specify a type signature. Bindings with arguments, i.e. f x = are not affected. See the link for details as to why this restriction exists.

Usually, you get an error message when the restriction is applied, but in this case GHCi is able to use type defaulting to change the type Num a => a to Integer.

The easiest way to dodge it is to either use an explicit type signature, or put

{-# LANGUAGE NoMonomorphismRestriction #-}

at the top of your module, or run GHCi with -XNoMonomorphismRestriction.

like image 104
hammar Avatar answered Oct 15 '22 14:10

hammar


As others have pointed out, this is caused by something called the "Monomorphism Restriction".

MR can be useful for writers of Haskell compilers, and there is controversy about whether or not it is worthwhile to have in the language in general. But there is one thing everyone agrees: at the GHCi prompt, MR is nothing but a nuisance.

MR will probably be turned off by default in this context in an upcoming version of GHC. For now, you should disable it in GHCi by creating a text file called ".ghci" in your home directory that contains a line like this:

:set -XNoMonomorphismRestriction
like image 31
Yitz Avatar answered Oct 15 '22 12:10

Yitz