如何将 foldrDefault 和 foldlDefault 与我的 foldMap 一起使用?

How do I use foldrDefault and foldlDefault with my foldMap?

我正在尝试完成 Phil Freeman 的 PureScript 书第 6.7 节中的练习 5。练习要我为以下类型编写一个 Foldable 实例。

data NonEmpty a = NonEmpty a (Array a)

我通过实现 foldMap.

编写了这个实例
instance foldableNonEmpty :: Foldable a => Foldable NonEmpty where
  foldMap :: forall a m. Monoid m => (a -> m) -> NonEmpty a -> m
  foldMap f (NonEmpty x xs) = (f x) <> (foldMap f xs)

  foldr :: forall a b. (a -> b -> b) -> b -> NonEmpty a -> b
  foldr f = foldrDefault f

  foldl f = foldlDefault f

但这会产生以下错误。

Error found:
in module Data.Hashable
at src/Data/Hashable.purs line 110, column 11 - line 110, column 23

  No type class instance was found for

    Data.Foldable.Foldable t2

  The instance head contains unknown type variables. Consider adding a type annotation.

while checking that type forall f a b. Foldable f => (a -> b -> b) -> b -> f a -> b
  is at least as general as type (a0 -> b1 -> b1) -> b1 -> NonEmpty a0 -> b1
while checking that expression foldrDefault
  has type (a0 -> b1 -> b1) -> b1 -> NonEmpty a0 -> b1
in value declaration foldableNonEmpty

where b1 is a rigid type variable
        bound at line 110, column 11 - line 110, column 23
      a0 is a rigid type variable
        bound at line 110, column 11 - line 110, column 23
      t2 is an unknown type

我想我收到错误是因为 foldr = foldrDefault 向编译器暗示 NonEmpty 已经是可折叠的,而这正是我要实例化的,但是我不知道如何使用默认的折叠实现。任何帮助将不胜感激。

我认为这实际上不是您使用默认值的问题。您似乎在您的实例上添加了一个不必要的 Foldable a 约束,我认为您不需要。所以你的实例可以是:

instance foldableNonEmpty :: Foldable NonEmpty where

去掉那个,我觉得剩下的就对了!

我在 try.purescript.org 编辑器中测试过:http://try.purescript.org/?gist=ce6ea31715bee2b65f3da374fd39181c