在 Purescript 中为 NonEmpty 编写 Functor 实例与编写 Eq 实例

Writing Functor instance vs. writing Eq instance for NonEmpty in Purescript

我目前正在通过阅读 Purescript by Example 这本书来学习 Purescript(到目前为止,这是我发现的唯一广泛涵盖该语言的资源之一)。

我正在尝试实现第 6.7 节(实例依赖项)中的练习,但我无法理解以下编译器错误:

我已经为数据类型 data NonEmpty a = NonEmpty a (Array a) 实现了 Semigroup 和 Eq 实例,如下所示:

instance eqNonEmpty :: Eq a => Eq (NonEmpty a) where
  eq (NonEmpty h1 t1) (NonEmpty h2 t2) = h1 == h2 && t1 == t2


instance semigroupNonEmpty :: Semigroup (NonEmpty a) where
  append (NonEmpty h1 t1) (NonEmpty h2 t2) = NonEmpty h1 (t1 <> [h2] <> t2)

但是当我尝试以同样的方式实现 Functor 实例时,我得到了上面的错误。 似乎有效的是:

instance functorNonEmpty :: Functor NonEmpty where
  map f (NonEmpty h t) = NonEmpty (f h) (map f t)

现在,这是为什么呢?我想不通。 谢谢!

这就是 Functor class 的定义方式:它适用于采用参数的类型。因此,例如,Functor class 将适用于 MaybeList,但不适用于 IntString ,同样不适用于 Maybe IntList String

类型 NonEmpty 确实有一个参数,因为它是这样定义的:

data NonEmpty a = ...

但是类型 NonEmpty a 接受参数,无论 a 可能是什么。

另一方面,classes EqSemigroup 期望没有任何参数的类型。所以这些 classes 可以应用于 IntStringMaybe Boolean 和任何其他没有参数的类型,包括 NonEmpty a,而不管 a 可能是。