簡體   English   中英

樹作為仿函數和可折疊的實例

[英]Tree as instance of functor and foldable

我正在為一個hw問題編寫一些代碼,它要求我們將樹的定義作為functor和foldable的一個實例。 當我寫下面的代碼時:

 import Data.Foldable
 import Data.Monoid

 data Tree a = Leaf a
              | Node [Tree a] 
     deriving (Show) 

 instance Functor (Tree) where
    fmap f (Leaf a) = Leaf (f a) 
    fmap f (Node [Tree a]) = fmap f [Tree a]

 instance Foldable (Tree) where
    foldMap f (Leaf a) = f a
    foldMap f (Node [Tree a]) = foldMap f `mappend` [Tree a]

出現以下錯誤:

hw.hs:10:19:
Not in scope: data constructor `Tree'
Perhaps you meant `True' (imported from Prelude)

hw.hs:10:38:
Not in scope: data constructor `Tree'
Perhaps you meant `True' (imported from Prelude)

hw.hs:14:22:
Not in scope: data constructor `Tree'
Perhaps you meant `True' (imported from Prelude)

hw.hs:14:54:
Not in scope: data constructor `Tree'
Perhaps you meant `True' (imported from Prelude)
Failed, modules loaded: none.

我哪里錯了?

謝謝!

[[更新]]

我根據下面答案中的建議對代碼進行了更改。 這是帶錯誤的代碼的鏈接。 如果有人看看它並告訴我哪里錯了,那就太好了。

http://snipt.org/Bahjg5

再次感謝!

你不能寫這個:

fmap f (Node [Tree a]) = ...

因為Tree是數據類型而不是數據構造函數。 在模式匹配中,您只能使用數據構造函數,在這種情況下,它們將是LeafNode 在這里,您甚至不需要匹配子樹的每個構造函數,因為您無論如何都要直接傳遞整個列表:

fmap f (Node t) = fmap f t

但實際上還存在另一個錯誤。 fmap的結果仍然需要是Tree因此您需要將結果放回Node

fmap f (Node t) = Node (fmap f t)

就像你已經在使用Leaf案一樣。


您可以將fmap視為修改結構內部值的內容,但根本不會更改結構的形狀 即。 在列表上進行映射將生成相同長度的列表,並且在樹上的映射應該生成相同的樹,具有所有相同的分支,但在葉節點中具有不同的值。

您可以將fold視為完全刪除結構的東西,然后找到將葉節點中的所有值組合成單個值的方法。 foldMap的類型有助於:

 foldMap :: (Foldable t, Monoid m) => 
         (a -> m) -- mapping function from `a` to the monoid result
      -> t a      -- A tree node containing values of type `a`
      -> m        -- a monoid

foldMap的結果不應該是Tree 它只是值,使用映射函數進行轉換,並使用它們的Monoid實例進行組合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM