2013-11-14 7 views
8

私はtreeの定義をfunctorと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

おかげで再び!

答えて

8

あなたはこれを書くことができません:データ型でないデータコンストラクタです

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

Treeので。パターンマッチでは、データコンストラクタのみを使用できます。この場合、LeafまたはNodeになります。

fmap f (Node t) = fmap f t 

しかし、実際にそこに別のエラーもあります:あなたはとにかくストレート全体のリストを渡しているので、ここでは、あなたも、子供の木のための各コンストラクタを一致させる必要はありません。

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

すでにLeafケースでやっているだけのように:fmapの結果はまだあなたがNode内のバック結果を配置する必要がありTreeする必要があります。


あなたは構造内部が、すべての構造の形状を変更せずに値を変更するものとしてfmapと考えることができます。すなわち、リストをマッピングすると、同じ長さのリストが生成され、ツリーをマッピングすると、すべてのブランチが同じで、リーフノードの値が異なる同一のツリーが生成されます。

foldは、構造を完全に削除して、葉ノードのすべての値を1つの値に結合する方法と考えることができます。 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インスタンスを使用して結合されます。

+2

技術的には、 'Tree'はコンストラクタの一種です。型コンストラクタです。だから、値を作る型とノードを作る。 – jozefg

+0

@jozefgややこしい!しかし、大丈夫、私はそれを変更しました:) –

+0

@PeterHallありがとう!あなたの提案に応じてコードを変更しましたが、まだエラーメッセージが表示されます エラーメッセージmsg: http://snipt.org/Bahjg5 – user2994154