3

尝试通过 foldr 函数实现列表计数

lengthList = foldr (\x s -> s + 1) 0 

给出以下错误

   * Ambiguous type variable `t0' arising from a use of `foldr'
  prevents the constraint `(Foldable t0)' from being solved.
  Relevant bindings include
    lengthList :: t0 a -> Integer (bound at lenListFoldr.hs:2:1)
  Probable fix: use a type annotation to specify what `t0' should be.
  These potential instances exist:
    instance Foldable (Either a) -- Defined in `Data.Foldable'
    instance Foldable Maybe -- Defined in `Data.Foldable'
    instance Foldable ((,) a) -- Defined in `Data.Foldable'
    ...plus one other
    ...plus 23 instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
* In the expression: foldr (\ x s -> s + 1) 0
  In an equation for `lengthList':
      lengthList = foldr (\ x s -> s + 1) 0

我该如何解决?

4

2 回答 2

3

添加类型签名:

lengthList :: [a] -> Int

或类似的东西。错误状态:“可能的修复:使用类型注释来指定 `t0' 应该是什么。” 换句话说,编译器无法推断类型。或者,正如评论所述:在上下文中使用函数,然后编译器将使用上下文来推断lengthList. 我相信该函数foldr使用类约束Foldable t;在您的情况下,编译器不知道lengthList折叠是什么。通过上面的签名,你一定t0会成为一个列表。看看 GHCi 给出的输出

:t foldr
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b

简而言之,GHC 可以找出a未使用的,b是 a Num,但它不知道t

于 2018-09-17T13:54:24.430 回答
3

可以通过类型定义来解决:

lengthList :: (Foldable t, Num a1) => t a2 -> a1

这很奇怪,但如果只是将函数粘贴到解释器,它会在没有类型定义的情况下正常工作

于 2018-09-17T13:57:36.847 回答