dmw*_*w64 1 haskell types pointfree monomorphism-restriction
关于Haskell中的类型,我有一个初学者的问题:有一个类似的函数:
f i xs = (sort xs) !! i
Run Code Online (Sandbox Code Playgroud)
如何在f0 xs = f 0 xs不明确使用xs的情况下定义函数?刚刚服用
f0 = f 0
Run Code Online (Sandbox Code Playgroud)
不起作用......
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
Run Code Online (Sandbox Code Playgroud)
如果你也这样做f0,一切都会正常工作:
f0 :: Ord a => [a] -> a
Run Code Online (Sandbox Code Playgroud)
现在的问题是,为什么ghci会推断出如此愚蠢的签名?这是可怕的单态限制的错.这意味着,每当你定义"作为常量( - 应用形式) "时,即一个简单的等式
c = any odd stuff
Run Code Online (Sandbox Code Playgroud)
然后编译器拒绝自动给出一个多态签名(比如,其中包含a类型变量).相反,它默认为"最简单可用"类型,对于Ord约束而言,遗憾的是它完全没用().
您可以关闭单态限制,然后即使没有签名也可以工作:
Prelude>:set -XNoMonomorphismRestriction
Prelude> let f0 = maximum
Prelude>:t f0
f0 :: Ord a => [a] - > a
但老实说,在顶层,你总是应该使用手动签名.