了解我的自定义数据类型的仿函数实例

Understanding a functor instance of my custom data type

我有这个数据类型:

data Arf a = Ser a [Arf a] deriving Show

实例化时 Functor 此代码有效:

instance Functor Arf where
    fmap f [] = []
    fmap f (Ser x xs) = Ser (f x) (map (fmap f) x)

为什么在 Ser 的第二个参数中使用 (map (fmap f) x) 而不是 (fmap f x)

我认为您的代码中有一个拼写错误:在最后一行的最后,它应该是 xs 而不是 x

说完这些,让我们来讨论一下地图。

内部 fmap 将函数 f 映射到 Arf a 类型。所以在这种情况下你可能会观察到:

     f ::     a ->     b
fmap f :: Arf a -> Arf b

但是那些 Arf a 值在列表中!那么,如何应用将 single Arf a 值转换为这些值的整个 list 的函数,转换它们中的每一个? map,当然!

因此外部 map 适用于整个列表:

          f ::       a  ->      b
     fmap f ::   Arf a  ->  Arf b
map (fmap f) :: [Arf a] -> [Arf b]

(根据 Fyodor 的评论修复...)

Why is (map (fmap f) xs) used instead of (fmap f xs) in the second argument to Ser?

Ser 的第二个参数是什么?这是一个 [Arf a],即 Arf 的列表。

如何将 f 应用于 xs 列表中的元素?你做 map ??? xs...

但是???函数是什么?

好吧,您希望它将 f 应用于那些 Arf 的内部,因此您需要它递归调用您正在定义的相同 fmap 函数,因此 ??? === fmap f.

因此map (fmap f) xs.