1

我对 Haskell 中的类型有一个初学者的问题:具有如下功能:

f i xs = (sort xs) !! i

如何在f0 xs = f 0 xs不显式使用 xs 的情况下定义函数?刚拿

f0 = f 0

不工作...

ghci 向我展示了以下类型:
f :: Ord a => Int -> [a] -> a
f0 :: [()] -> ()
但是 ":tf 0" 给出了f 0 :: Ord a => [a] -> a.

这是为什么?为什么我会为 f0 获得这种类型?为什么“f0”的类型和“f 0”的类型有什么区别?

非常感谢您的任何建议

4

1 回答 1

5

它与您的特定定义无关:如果您使用标准实现(应该这样做!),也会发生同样的事情。

Prelude> 让 f0 = 最大
Prelude> :t f0
f0 :: [()] -> ()

无论如何,首先你应该给f一个签名。

f :: Ord a => Int -> [a] -> a

如果你也这样做f0,一切都会正常工作:

f0 :: Ord a => [a] -> a

现在的问题是,为什么 ghci 会推导出这样一个愚蠢的签名?这是Dreaded Monomorphism Restriction的错。这意味着,每当您将某些东西定义为“常数(-应用形式) ”时,即一个简单的方程式

c = any odd stuff

然后编译器拒绝自动为其提供多态签名(例如,其中包含a类型变量)。相反,它默认为“最简单的可用”类型,不幸的是,它对于Ord约束是完全无用的()

您可以关闭单态限制,即使没有签名它也可以工作:

Prelude> :set -XNoMonomorphismRestriction
Prelude> let f0 = maximum
Prelude> :t f0
f0 :: Ord a => [a] -> a

但老实说,无论如何,您应该始终使用手动签名。

于 2014-04-16T20:29:49.947 回答