Haskell - 树的fmap和foldMap

问题描述 投票:3回答:2

我是新的哈斯克尔,我有点卡住了我

data Tree a = Empty | Leaf a | Branch a (Tree a) (Tree a)
    deriving (Show)

我想创建一个fmap和一个foldMap,所以我试过了

instance Functor Tree where
    fmap f (Leaf x) = Leaf (f x)
    fmap f (Branch a left right) = Branch a (fmap f left) (fmap f right)

它根本不起作用,我不明白为什么,我很确定问题就在这里

.. = Branch a (fmap f left) (fmap f right)

无论如何,我真的可以使用fmap和foldMap的一些帮助,实际上我有一个想法,但我没有正确的语法。

谢谢您的帮助。

haskell
2个回答
7
投票

您忘记在f节点中包含的as上应用函数Branch,否则您只在叶子上应用函数。而且,你忘记了Empty构造函数的情况。

instance Functor Tree where
  fmap f Empty = Empty
  fmap f (Leaf x) = Leaf (f x)
  fmap f (Branch a left right) = Branch (f a) (fmap f left) (fmap f right)

2
投票

顺便说一句,我认为您的数据声明可能不太正确(或者说不是标准的)。通常一个人定义

data Tree a = Nil | Node a (Tree a) (Tree a)

也就是说,Tree要么是一个空节点(Nil),要么是包含一个值和两个子树的Node。通过这种方式,您可以将没有分支的非空树表示为Node a Nil Nil

无论如何,要正确定义此类型的Functor实例(Tree类型的实例类似),您需要为fmap :: (a -> b) -> Tree a -> Tree b类型的所有可能值定义Tree a - 在本例中为空值和非空值。您的实现正处于正确的轨道上,但是您忘记将f应用于非空节点中包含的值:

instance Functor Tree where
  fmap _ Nil = Nil -- nothing to fmap in this case
  fmap f (Node a left right) = Node (f a) (fmap f left) (fmap f right)
© www.soinside.com 2019 - 2024. All rights reserved.