[英]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.
我哪里錯了?
謝謝!
[[更新]]
我根據下面答案中的建議對代碼進行了更改。 這是帶錯誤的代碼的鏈接。 如果有人看看它並告訴我哪里錯了,那就太好了。
再次感謝!
你不能寫這個:
fmap f (Node [Tree a]) = ...
因為Tree
是數據類型而不是數據構造函數。 在模式匹配中,您只能使用數據構造函數,在這種情況下,它們將是Leaf
或Node
。 在這里,您甚至不需要匹配子樹的每個構造函數,因為您無論如何都要直接傳遞整個列表:
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.