2017-04-26 7 views
1

다음 코드에서 cataM을 트리 하향식으로 트래버스하는 것이 가능합니다 (현재 상향식이 아닌 상향식이 아닌 방법).cataM에 대한 평가 순서

는 내가 다른 foldMap를 구현해야합니다 생각하지만, 아이들이 t의 더 예를하지 않았다있는 방법 branch 이후 어린이 전에 branch 노드 자체를 처리하는 방법을? 당신은 또한 마트 료가 제공하는 기능 topDownCataM을 찾고있는 것처럼

module Catatree where 

import Data.Foldable 
import Data.Traversable 
import Data.Monoid 
import Data.Generic 
import Prelude 
import Control.Monad.Writer 
import Control.Monad.Eff (Eff) 
import Control.Monad.Eff.Console (CONSOLE, log, logShow) 

import Data.Functor.Mu (Mu) 
import Matryoshka (class Corecursive, class Recursive, Algebra, AlgebraM, cata, embed, cataM, project) 

data TreeF a t = Leaf | Branch a (Array t) 

type IntTree = Mu (TreeF Int) 

derive instance treeGeneric :: (Generic a, Generic t) => Generic (TreeF a t) 
derive instance treeFunctor :: Functor (TreeF a) 

instance showTree :: (Generic a, Generic t) => Show (TreeF a t) where 
    show = gShow 

instance treeTraversable :: Traversable (TreeF a) where 
    -- traverse :: forall a b m. Applicative m => (a -> m b) -> t a -> m (t b) 
    traverse f Leaf = pure Leaf 
    traverse f (Branch a children) = Branch a <$> traverse f children 
    sequence f = sequenceDefault f 


instance treeFoldable :: Foldable (TreeF a) where 
    foldr f = foldrDefault f 
    foldl f = foldlDefault f 
    -- foldMap :: forall a m. Monoid m => (a -> m) -> f a -> m 
    foldMap f Leaf = mempty 
    foldMap f (Branch a children) = foldMap f children 

evalM :: AlgebraM (Writer (Array String)) (TreeF Int) Int 
evalM Leaf = do 
    tell $ [ "visiting leaf " ] 
    pure 4 
evalM (Branch a children) = do 
    tell $ [ "visiting branch " <> show a ] 
    pure 2 

runM :: forall t. Recursive t (TreeF Int) => t -> Writer (Array String) Int 
runM = cataM evalM 

branch :: forall t. Corecursive t (TreeF Int) => Int -> Array t -> t 
branch i children = embed (Branch i children) 

exp :: IntTree 
exp = branch 3 [(branch 1 []), (branch 2 [])] 

main :: forall eff. Eff (console :: CONSOLE | eff) Unit 
main = do 
    logShow $ runWriter $ runM exp 
    -- outputs (Tuple 2 ["visiting branch 1","visiting branch 2","visiting branch 3"]) 

답변

1

는 소리가 난다.