关于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"的类型有什么区别?
非常感谢您提出任何建议
它与您的特定定义无关:如果您使用标准实现(如您所愿!),则会发生同样的事情.
前奏>让f0 =最大
前奏>:t f0
f0 :: [()] - >()
无论如何,首先你应该f
签名.
f :: Ord a => Int -> [a] -> a
如果你也这样做f0
,一切都会正常工作:
f0 :: Ord a => [a] -> a
现在的问题是,为什么ghci会推断出如此愚蠢的签名?这是可怕的单态限制的错.这意味着,每当你定义"作为常量( - 应用形式) "时,即一个简单的等式
c = any odd stuff
然后编译器拒绝自动给出一个多态签名(比如,其中包含a
类型变量).相反,它默认为"最简单可用"类型,对于Ord
约束而言,遗憾的是它完全没用()
.
您可以关闭单态限制,然后即使没有签名也可以工作:
Prelude>:set -XNoMonomorphismRestriction
Prelude> let f0 = maximum
Prelude>:t f0
f0 :: Ord a => [a] - > a
但老实说,在顶层,你总是应该使用手动签名.