6

我试图用 ghci 检查这个 stackoverflow 答案并得到以下错误:

> import Data.List
> let m = head . sort
> m [2,3,4]

<interactive>:5:4:
   No instance for (Num ()) arising from the literal `2'
   Possible fix: add an instance declaration for (Num ())
   In the expression: 2
   In the first argument of `m', namely `[2, 3, 4]'
   In the expression: m [2, 3, 4]

不幸的是,我无法在书面的 haskell 文件中重现该错误:

-- file.hs
import Data.List

main = do
    let m = head . sort
    putStrLn $ show $ m [2,3,4]

运行这个文件runhaskell file.hs给了我期望的值2。我在 ghci 会话中的错误是什么?

编辑:我注意到,该函数m在 ghci 中有一个奇怪的类型:

> import Data.List
> let m = head . sort
> :t m
m :: [()] -> ()

为什么会这样?它不应该有类型Ord a => [a] -> a吗?对于sort并且head我得到预期的类型:

> :t sort
sort :: Ord a => [a] -> [a]
> :t head
head :: [a] -> a
4

1 回答 1

7

这是可怕的单态限制的错误。基本上,因为您没有为 指定类型m,GHCi 会为您猜测它。在这种情况下,它猜测m应该有 type [()] -> (),即使这显然不是你想要的。只需m输入一个类型签名就GHCi可以了。

> :set +m  -- multiline expressions, they're handy
> let m :: Ord a => [a] -> a
|     m = head . sort

您可以使用禁用单态限制

> :set -XNoMonomorphismRestriction

但它通常非常方便,否则您必须为通常不会在交互模式下使用的事物指定许多类型。

于 2014-04-03T13:55:17.840 回答