使用uncurry函数的特定类型推断 [英] Specific type inference using uncurry function

查看:163
本文介绍了使用uncurry函数的特定类型推断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在玩GHCi中的 uncurry 函数,我发现了一些我根本无法理解的东西。当我将 uncurry 应用于(+)函数并将其绑定到某些变量(如下面的代码)时,编译器推断它的类型特定于整数

  Prelude>让add = uncurry(+)
Prelude> :t add
add ::(Integer,Integer) - >整数

但是,如果要求获得以下表达式的类型(我期望的是)正确的结果:

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

会导致什么? GHCi是特别的吗?



同样适用于 let add'=(+)



注意:我无法复制使用已编译的文件 这与ghci没有任何关系。这是单态限制令人恼火。如果您尝试编译以下文件:

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

你会得到一个错误。如果您展开:

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

一切都很好,如预期。单态限制拒绝使看起来像一个值(即在等号左边没有参数定义)类型类型多态性的东西,因为这会破坏通常会发生的高速缓存。例如。

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $数字a)=> a
bar =昂贵的计算

foo 保证只计算一次(至少在GHC中),而每次提及 bar 时将被计算。如果你只使用一次函数(或者总是使用函数),那么单形态限制就是通过默认为前者来避免后者的情况。在同一类型),类型推断将负责为你推断正确的类型。在那种情况下,ghci通过更快地猜测来做一些稍微不同的事情。但是,在两种不同的类型中使用它会显示发生了什么。



如果有疑问,请使用类型签名(或者使用 { - #LANGUAGE NoMonomorphismRestriction# - } )。


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.

解决方案

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 #-}).

这篇关于使用uncurry函数的特定类型推断的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆