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"])