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

use*_*579 2 types class functor purescript

我目前正在通过阅读Purescript by Example书来学习 Purescript (迄今为止我发现的唯一涵盖该语言的资源之一)。

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

在此处输入图片说明

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

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)

Run Code Online (Sandbox Code Playgroud)

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

instance functorNonEmpty :: Functor NonEmpty where
  map f (NonEmpty h t) = NonEmpty (f h) (map f t)
Run Code Online (Sandbox Code Playgroud)

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

Fyo*_*kin 6

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

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

data NonEmpty a = ...
Run Code Online (Sandbox Code Playgroud)

但类型NonEmpty a不会带一个参数,不管是什么a可能。

而另一方面,类EqSemigroup期望一个没有任何参数的类型。因此,这些类可以适用于IntStringMaybe Boolean,和任何其他类型的无参数,包括NonEmpty a,不管是什么a可能。

  • 对,就是这样。有时还可能有一个显式的类型签名,例如“class Functor (f :: Type -&gt; Type)”。如果编译器无法像从“fa”那样从使用中推断出类型,则可能需要这样做。 (2认同)