Specific type inference using the unaccounted function

I played with the uncurry function in GHCi, and I found something that I could not get at all. When I apply uncurry to a (+) function and bind it to some variable, as in the code below, the compiler indicates its type to be specific to Integer :

 Prelude> let add = uncurry (+) Prelude> :t add add :: (Integer, Integer) -> Integer 

However, when querying for the type of the following expression, I get (what I expect) the correct result:

 Prelude> :t uncurry (+) uncurry (+) :: (Num a) => (a, a) -> a 

What would it cause? Is this especially important for GHCi?

The same goes for let add' = (+) .

NOTE. I could not reproduce this using a compiled file.

+6
types haskell ghc monomorphism-restriction
source share
2 answers

This has nothing to do with ghci. This restriction of monomorphism is annoying. If you try to compile the following file:

 add = uncurry (+) main = do print $ add (1,2 :: Int) print $ add (1,2 :: Double) 

You will receive an error message. If you expand:

 main = do print $ uncurry (+) (1,2 :: Int) print $ uncurry (+) (1,2 :: Double) 

Everything is fine, as expected. The restriction of monomorphism refuses to do something that β€œlooks like a value” (that is, Defined with no arguments on the left side of the equality) typeclass is polymorphic because it defeats the caching that usually happens. For example.

 foo :: Integer foo = expensive computation bar :: (Num a) => a bar = expensive computation 

foo guaranteed that it will be evaluated only once (well, at least in the GHC), while bar will be evaluated every time it is mentioned. Limiting monomorphism tries to save you from the latter case, by default, if it looks like what you wanted.

If you use the function only once (or always in the same type), enter the output that will take care of inferring the correct type for you. In this case, ghci does something a little different, guessing earlier. But using it on two different types shows what is happening.

If in doubt, use a type signature (or disable the wretched thing with {-# LANGUAGE NoMonomorphismRestriction #-} ).

+21
source share

There, magic is associated with extended default rules with ghci. Basically, among other things, Num constraints are divided by default into Integer and Floating constraints by Double, if there would otherwise be an error (in this case, due to the restriction of evil monomorphism).

+4
source share

All Articles