Specific type inference using uncurry function

大憨熊 提交于 2019-12-07 03:21:02

问题


I've been playing with the uncurry function in GHCi and I've found something I couldn't quite get at all. When I apply uncurry to the (+) function and bind that to some variable like in the code below, the compiler infers its type to be specific to Integer:

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

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

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

What would cause that? Is it particular to GHCi?

The same applies to let add' = (+).

NOTE: I could not reproduce that using a compiled file.


回答1:


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

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

You will get an error. If you expand:

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

Everything is fine, as expected. The monomorphism restriction refuses to make something that "looks like a value" (i.e. defined with no arguments on the left-hand side of the equals) typeclass polymorphic, because that would defeat the caching that would normally occur. Eg.

foo :: Integer
foo = expensive computation

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

foo is guaranteed only to be computed once (well, in GHC at least), whereas bar will be computed every time it is mentioned. The monomorphism restriction seeks to save you from the latter case by defaulting to the former when it looks like that's what you wanted.

If you only use the function once (or always at the same type), type inference will take care of inferring the right type for you. In that case ghci is doing something slightly different by guessing sooner. But using it at two different types shows what is going on.

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




回答2:


There's magic involved in extended defaulting rules with ghci. Basically, among other things, Num constraints get defaulted to Integer and Floating constraints to Double, when otherwise there would be an error (in this case, due to the evil monomorphism restriction).



来源:https://stackoverflow.com/questions/4999020/specific-type-inference-using-uncurry-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!