Haskell:`Num [a] =>之间有什么区别? a`和'Num a =>并[a]`

时间:2010-07-07 04:11:04

标签: 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

由于上述原因,它显然不起作用;但是,如果我删除了我的签名,它会编译(不确定原因,请解释),并且我得到了这个签名:

elemNum :: (Num [a], Eq t) => t -> [t] -> [a]

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

2 个答案:

答案 0 :(得分:8)

Num a表示类型a可以视为数字;例如。您可以将两个a添加到一起以获得新的a,或者您可以否定a并获得aIntegerDouble属于此类别。

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

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

foo (x:xs) = xs + 1

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

答案 1 :(得分:2)

Num [a]约束意味着list是Num类型的实例。

foo :: Num a => [a]

是作为Num类型类

的实例的值列表
bar :: Num [a] => [a]

是值列表,它是Num类型类的实例。这意味着您可以使用Num中的所有函数并从数字文字构造列表,因此下面的代码有效,但需要FlexibleContexts

bar :: Num [a] => [a]
bar = 42

P.S。你这里不需要辅助功能。 elemNum e l = f el⇒elemNum= f。所以你可以把你的函数写成

elemNum _ [] = 0
elemNum e (x:xs)
  | x == e = 1 + f e xs
  | otherwise = f e xs