为什么我在函子实例中收到 GHC 无法匹配类型错误?

Jam*_*ter 2 haskell functor ghc

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

\n
module TreeN where\n\ndata TreeN a = LeafN a | ParentN a [TreeN a] deriving (Eq, Show)\n\ninstance Functor TreeN where\n\nfmap f (LeafN x) = LeafN (f x)\nfmap f (ParentN x children) = (ParentN (f x) (TreeN.fmap f children))\n\n
Run Code Online (Sandbox Code Playgroud)\n

我收到此错误:

\n
src/TreeN.hs:7:1: error:\n    \xe2\x80\xa2 Couldn't match type \xe2\x80\x98TreeN t\xe2\x80\x99 with \xe2\x80\x98[TreeN t]\xe2\x80\x99\n      Expected type: (t -> a) -> [TreeN t] -> [TreeN a]\n        Actual type: (t -> a) -> TreeN t -> TreeN a\n    \xe2\x80\xa2 Relevant bindings include\n        fmap :: (t -> a) -> [TreeN t] -> [TreeN a]\n          (bound at src/TreeN.hs:7:1)\n  |\n7 | fmap f (LeafN x) = LeafN (f x)\n  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...\nFailed, no modules loaded.\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

我也尝试拼写这个:

\n
map :: (a -> b) -> f a -> f b\n
Run Code Online (Sandbox Code Playgroud)\n

但这会导致不同的错误。我无法判断 GHC 是否出错,因为它两次看到同一件事,或者您是否应该明确说明这一点,而明确说明它会暴露一些其他问题。

\n

我究竟做错了什么?

\n

Wil*_*sem 7

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

instance Functor TreeN where
    fmap f (LeafN x) = LeafN (f x)
    fmap f (ParentN x children) = ParentN (f x) (map (fmap f) children)
Run Code Online (Sandbox Code Playgroud)

然而,您的实现Functor是“标准”实现,您可以使用DeriveFunctor语言扩展并使用:

{-# LANGUAGE DeriveFunctor #-}

data TreeN a = LeafN a | ParentN a [TreeN a] deriving (Eq, Functor, Show)
Run Code Online (Sandbox Code Playgroud)