Haskell:`Num [a] => a`和`Num a => [a]之间的差异是什么?

Eva*_*oll 3 haskell types typeclass

显然,我的类型签名已关闭.我已经发现了原因.现在,我有兴趣了解更多有关GHCI推断签名的错误信息.我试图让这段代码工作:

elemNum :: (Eq a, Num b) => a -> [a] -> b
elemNum e l = f e l
  where  f _ [] = []  -- this was my typo, supposed to read 0
         f e (x:xs)
             | x == e = 1 + f e xs
             | otherwise = f e xs
Run Code Online (Sandbox Code Playgroud)

由于上述原因,它显然不起作用; 但是,如果我删除我的签名,它会编译(不知道为什么,请解释),我得到这个签名:

elemNum :: (Num [a], Eq t) => t -> [t] -> [a]
Run Code Online (Sandbox Code Playgroud)

我以前从未见过类型类Num [a].这意味着什么,以及它与之相比如何(Num a) => [a].

luq*_*qui 8

Num a意味着该类型a可以被视为一个数字; 例如.你可以将两个as加在一起以获得一个新的,a或者你可以否定一个a并得到一个a. IntegerDouble属于这一类.

相应地,Num [a]意味着该类型[a]可以被视为数字.即你可以将两个列表添加到一起a以获得新的列表a.这不太可能有意义,因为没有列表是数字(默认情况下).这意味着您正在处理列表,就像它是一个数字,导致GHC得出结论,您必须希望列表像数字一样,从而添加适当的约束.

这样的约束可能来自如下函数:

foo (x:xs) = xs + 1
Run Code Online (Sandbox Code Playgroud)

xs 模式匹配作为列表的尾部,因此它本身就是一个列表,然后你添加它,将列表视为一个数字.

  • 是的,你可以.例如,如果你想提供多项式,但总的来说这是一个坏主意.实例Num a => Num [a]其中fromIntegral a = [a](a:as)+(b:bs)=(a + b):( as + bs)[] + bs = bs as + [] =作为...... (4认同)
  • 从技术上讲,你可以做任何类型类的实例(提供种类匹配),例如`instance Num [a] from fromInteger x = undefined; x + y = undefined`等.但它显然没有用. (3认同)