为什么我在 Functor 实例中遇到 GHC 无法匹配类型错误?

Why Am I Getting GHC Couldn't Match Type Error in Functor Instance?

我正在尝试编写一个 Functor 实例:

module TreeN where

data TreeN a = LeafN a | ParentN a [TreeN a] deriving (Eq, Show)

instance Functor TreeN where

fmap f (LeafN x) = LeafN (f x)
fmap f (ParentN x children) = (ParentN (f x) (TreeN.fmap f children))

我得到这个错误:

src/TreeN.hs:7:1: error:
    • Couldn't match type ‘TreeN t’ with ‘[TreeN t]’
      Expected type: (t -> a) -> [TreeN t] -> [TreeN a]
        Actual type: (t -> a) -> TreeN t -> TreeN a
    • Relevant bindings include
        fmap :: (t -> a) -> [TreeN t] -> [TreeN a]
          (bound at src/TreeN.hs:7:1)
  |
7 | fmap f (LeafN x) = LeafN (f x)
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
Failed, no modules loaded.

GHC 认为我想将 fmap 的输入和输出包装在另一层结构中,这对我来说是个谜。

我也试过拼写这个:

map :: (a -> b) -> f a -> f b

但这会导致不同的错误。我不知道 GHC 是否因为两次看到相同的东西而出错,或者你是否应该对此明确说明并明确说明它会暴露一些其他问题。

我做错了什么?

您的parentN有一个列表,共TreeN个,因此您需要对所有子项执行映射:

instance Functor TreeN where
    fmap f (LeafN x) = LeafN (f x)
    fmap f (ParentN x children) = ParentN (f x) (<strong>map (fmap f)</strong> children)

您的 Functor 实现是“标准”实现,您可以使用 DeriveFunctor language extension 并使用:

{-# LANGUAGE <strong>DeriveFunctor</strong> #-}

data TreeN a = LeafN a | ParentN a [TreeN a] deriving (Eq, <strong>Functor</strong>, Show)