这个 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
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
.
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
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
.