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
语句。有人可以解释为什么这样写吗?
答案 0 :(得分:3)
如果您查看Node
的结构,它包含f (GenTree f a)
,那么如果我们查看相关表达式的类型:
fmap f (Node ts) = Node (fmap (fmap f) ts)
f
此处的类型为a -> b
ts
的类型为f (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
。