这个 Functor 实例是如何实现的?

How is this Functor instance implemented?

data GenTree f a -- kind (* -> *) -> * -> *
    = Node (f (GenTree f a))
    | Leaf a

instance Functor f => Functor (GenTree f) where
    fmap f (Node ts) = Node (fmap (fmap f) ts)
    fmap f (Leaf x)  = Leaf (f x)

我不明白上面 Functor 实例中的 fmap (fmap f) ts 语句。谁能解释一下为什么这样写?

如果您查看 Node 的结构,它包含一个 f (GenTree f a),所以如果我们查看相关表达式的类型:

fmap f (Node ts) = Node (fmap (fmap f) ts)

f 这里的类型是 a -> b

tsf (GenTree f a)类型,但是我们要注意,这个表达式中的f并不是上面的函数,而是类型构造函数。为了消除混淆,我们将上面的函数重命名为 g,如下所示:

fmap g (Node ts) = Node (fmap (fmap g) ts)

现在,为了应用我们的函数 g,我们需要获取 a 的实际值。我们知道我们的 f 类型构造函数有一个 Functor 实例,所以如果我们映射它,我们会得到一个 GenTree f a:

fmap (\tree -> ...) ts

现在我们有了 GenTree 我们可以递归调用 fmap 这样在某个时候我们将到达叶子并将我们的函数实际应用于值,如果我们写这在它的所有样板中,看起来像这样:

fmap g (Node ts) = Node (fmap (\tree -> fmap g tree) ts)

所以本质上它是这样写的,因为我们需要 fmap 覆盖 f 类型构造函数和实际的 GenTree.