List 使用foldr的Haskell类型类
我使用foldr编写了一个函数,用于确定列表或字符串的长度。我有点困惑,为什么Haskell确定类型类为Num。这个类中肯定不包括字符串吗?然而Haskell坚持必须这样做,否则函数将无法工作。有人能帮忙澄清一下这是为什么吗List 使用foldr的Haskell类型类,list,haskell,types,typeclass,List,Haskell,Types,Typeclass,我使用foldr编写了一个函数,用于确定列表或字符串的长度。我有点困惑,为什么Haskell确定类型类为Num。这个类中肯定不包括字符串吗?然而Haskell坚持必须这样做,否则函数将无法工作。有人能帮忙澄清一下这是为什么吗 myLength' :: (Num a) => [a] -> Int myLength' xs = foldr (\x acc -> 1 + acc) 0 xs 我认为您的声明可能使您的类型签名过于具体。以下是我在GHCi中得到的信息: :t foldr
myLength' :: (Num a) => [a] -> Int
myLength' xs = foldr (\x acc -> 1 + acc) 0 xs
我认为您的声明可能使您的类型签名过于具体。以下是我在GHCi中得到的信息:
:t foldr
foldr::(a->b->b)->b->a]->b
>:t foldr(\x acc->acc+1)
... :: 数值b=>b->[a]->b
+
是Num
约束的来源。它只适用于类型b
,因为acc
的类型与b
相统一。由于我们没有使用x::a
执行任何操作,因此不会产生进一步的约束
:t foldr(\x acc->acc+1)0
... :: 数值b=>[a]->b
0
很容易与Num b=>b
相结合,除了我们放下一个箭头外,没有任何变化
:t\xs->foldr(\x acc->acc+1)0 xs
... :: 数值b=>[a]->b
我们引入了一个没有特定类型的参数xs
,它很容易与[a]
统一。没有什么变化。所以我们的最终类型应该是
myLength::(Num b)=>a]>b
myLength=foldr(\\uACC->1+acc)0
这对字符串有效myLength“hello”=>5
等等
正如Lee在评论中提到的,foldr
的类型在GHC 7.10中更改为Foldable t=>(a->b->b->ta->b
,作为的一部分,它允许在许多不同的数据结构上使用foldr
,而不仅仅是列表。在GHC 7.10上,您的函数确实会有一个类型推断myLength::(可折叠的t,Num b)=>ta->b
。请注意(可折叠的t)=>ta如何概括[a]
万岁类型您使用的是哪个版本?GHC 7.10将函数类型推断为(Num b,Foldable t)=>ta->b
。GHC 7.8.4如果这有帮助的话,非常感谢您如此清晰、简洁地解释一切!