Haskell 求和函数的不同类型

Haskell 求和函数的不同类型,haskell,types,sum,foldable,Haskell,Types,Sum,Foldable,我是哈斯克尔的新手,所以这可能是个愚蠢的问题。我在读一本书,上面写着::type sum应该显示sum::(Num a)=>[a]->a。相反,消息是sum::(Num a,Foldable t)=>ta->a。正如我所看到的,这种差异是由于——我认为——两个不同的和函数的存在。也许这有点像Java中的多态性,我才刚刚开始,不知道Haskell是如何工作的 所以我的问题是:如何使用sum函数,类型是sum::(numa)=>[a]->a,而不是另一个?你能解释一下这是怎么回事吗 正如我所看到的,

我是哈斯克尔的新手,所以这可能是个愚蠢的问题。我在读一本书,上面写着:
:type sum
应该显示
sum::(Num a)=>[a]->a
。相反,消息是
sum::(Num a,Foldable t)=>ta->a
。正如我所看到的,这种差异是由于——我认为——两个不同的和函数的存在。也许这有点像Java中的多态性,我才刚刚开始,不知道Haskell是如何工作的

所以我的问题是:如何使用sum函数,类型是
sum::(numa)=>[a]->a
,而不是另一个?你能解释一下这是怎么回事吗

正如我所看到的,这种差异是由于——我认为——两个不同的和函数的存在。也许这有点像Java中的多态性

事实上,这是多态性,尽管不是以这种方式(见本答案末尾的p.S.)。请注意

sum :: (Num a) => [a] -> a
。。。在要求和的数字类型中已经是多态的,因此它可以用于
Integer
列表和
Double
列表。这和…之间的区别是什么

sum :: (Num a, Foldable t) => t a -> a
。。。在容器的类型中,这个
sum
也是多态的:

对于要与
sum
一起使用的容器类型,它必须具有的实例,该实例包含的函数与
sum
类似,可以表示为将容器展平为列表,然后以某种方式将其折叠


附言:你的书与你所看到的有所不同,因为直到最近,前奏曲中的
sum
函数还使用不太通用的、列表特定的类型,而你的书在更改之前就已经出现了。拥有两个名为
sum
的不同函数,即使其中一个函数严格来说比另一个函数更通用,也会导致名称冲突(出于类似的原因,我导入了上面示例中限定的
Data.Set
模块——这样做是一个好主意,因为它定义了一些与前奏曲函数冲突的函数,例如
map
,并用
S.map
来限定它们可以避免任何问题).

列表
sum
Prelude
中,即默认情况下在范围内,因此如果您不做任何特殊操作,您将使用它。要引用另一个
sum
,您需要导入
数据。可折叠的
。那么您到底有什么疑问?如果有一些歧义,编译器应该报告。@laugedelic截至最近的GHC rel很容易,前奏曲
sum
数据中的前奏曲相同。可折叠的
。自GHC 7.10以来,前奏曲中的几个函数都有通用签名。不再有一个
sum::Num a=>[a]->a
-新的
sum:(Num a,可折叠的t)=>ta->a
仍在列表上工作(与旧的一样)但它现在也可以用于其他事情(或者)@duplode Cool!我不知道这些变化。很容易被新前奏曲类型的普遍性搞糊涂。每当你在约束中看到可折叠的t
,在心里用
[a]
替换每个t
,以获得更简单的情况。
GHCi> -- +t makes GHCi print the types automatically.
GHCi> :set +t
GHCi> sum [1 :: Integer, 2, 3]
6
it :: Integer
GHCi> sum [1 :: Double, 2, 3]
6.0
it :: Double
GHCi> import qualified Data.Set as S
GHCi> :t S.fromList
S.fromList :: Ord a => [a] -> S.Set a
GHCi> sum (S.fromList [1 :: Double, 2, 3])
6.0
it :: Double