Haskell: `Num [a] => a`和 `Num a => [a]`有什么区别

标签 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] 相比如何>.

最佳答案

Num a 表示 a 类型可以被视为一个数字;例如。你可以将两个 a 加在一起得到一个新的 a 或者你可以否定一个 a 并得到一个 a . IntegerDouble 属于这一类。

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

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

foo (x:xs) = xs + 1

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

关于Haskell: `Num [a] => a`和 `Num a => [a]`有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3191867/

相关文章:

haskell - Haskell子类的解释

haskell - Cabal 在 NixOS 上构建时找不到外部库

user-interface - 使用 ZeroMQ 进行跨平台开发?

scala - 是否可以将类型参数的类型参数传播到 Scala 中的参数化类?

c++ - 代表类型的变量?运行时继承?

haskell - 为什么 Haskell 中的这种类型注释是必要的?

haskell - 类型类和重载,有什么联系?

optimization - 如何更快地列出目录?

Haskell 类型同义词

javascript - 使用 Typescript 时,如何创建类装饰器以将新方法混合到 React 组件中?