gpt4 book ai didi

haskell - 使用 uncurry 函数的特定类型推断

转载 作者:行者123 更新时间:2023-12-04 13:04:51 25 4
gpt4 key购买 nike

我一直在玩uncurry在 GHCi 中运行,我发现了一些我根本无法得到的东西。当我申请 uncurry(+)函数并将其绑定(bind)到下面代码中的某个变量,编译器推断其类型特定于 Integer :

Prelude> let add = uncurry (+)
Prelude> :t add
add :: (Integer, 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)

一切都很好,正如预期的那样。单态限制拒绝使“看起来像一个值”的东西(即在等号的左侧没有参数定义)类型类多态,因为这会破坏通常会发生的缓存。例如。
foo :: Integer
foo = expensive computation

bar :: (Num a) => a
bar = expensive computation
foo保证只计算一次(至少在 GHC 中),而 bar每次被提及时都会计算。单态性限制旨在通过在看起来像您想要的那样时默认为前者来将您从后一种情况中拯救出来。

如果您只使用该函数一次(或始终使用相同的类型),类型推断将负责为您推断出正确的类型。在这种情况下,ghci 通过更早地猜测来做一些稍微不同的事情。但是在两种不同的类型上使用它显示了正在发生的事情。

如有疑问,请使用类型签名(或使用 {-# LANGUAGE NoMonomorphismRestriction #-} 关闭可悲的东西)。

关于haskell - 使用 uncurry 函数的特定类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4999020/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com