奇怪的功能类型

时间:2014-04-16 20:12:55

标签: haskell types pointfree monomorphism-restriction

我有一个关于Haskell中类型的初学者问题:有类似的函数:

f i xs = (sort xs) !! i

如何在不明确使用xs的情况下定义函数f0 xs = f 0 xs? 刚刚接受

f0 = f 0

不起作用......

ghci向我展示了愚蠢的类型:
f :: Ord a => Int -> [a] -> a
f0 :: [()] -> ()
但是“:t f 0”给出了f 0 :: Ord a => [a] -> a

为什么?为什么我为f0获得此类型?为什么“f0”的类型和“f 0”的类型之间有什么区别?

非常感谢您提出任何建议

1 个答案:

答案 0 :(得分:5)

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

  

前奏>设f0 =最大
  前奏> :t f0
  f0 :: [()] - > ()

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

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

如果您也为f0执行此操作,则一切正常:

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

现在的问题是,为什么ghci会推断出如此愚蠢的签名?它是Dreaded Monomorphism Restriction的错。这意味着,每当你定义一些东西"作为常量( - applicative form)",即一个简单的等式

c = any odd stuff

然后编译器拒绝自动给出多态签名(例如,其中包含a类型变量)。相反,它默认为"最简单的可用"类型,对于Ord约束而言,遗憾的是它是完全无用的()

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

  

前奏> :set -XNoMonomorphismRestriction
  前奏>设f0 =最大
  前奏> :t f0
  f0 :: Ord a => [a] - >一个

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