purescriptrecursion-schemescatamorphism# Order of evaluation for cataM

In the following code, how is it possible to have cataM traverse the tree top-down (and not bottom-up as it is the case currently) ?

I guess I should implement `foldMap`

differently but how to process the `branch`

node itself before the children since `branch`

has no instance of `t`

which are not children?

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

Solution

It sounds like you're looking for the function `topDownCataM`

that is also provided by Matryoshka. ðŸ˜„

- How to debug with PureScript?
- Automatically focus input element after creation in purescript-halogen
- Why do instances in PureScript have names?
- vscode extension with a typed functional language
- Purescript default `Show` instance for records
- What is () defined as in Purescript? What does it mean?
- Purescript Complex zero element (Purescipt by example exercies)
- Using an ADT's constrctor as a type in Purescript
- How do I get the current browser URL with purescript?
- purescript halogen - render elements or nothing conditionally
- Why purescript can infer the Row.Cons contraint?
- StateT monad inside Handler in purescript-express
- How do composition and currying interact?
- Which is a more efficient version of "takeEnd" function
- purescript data as array of all possible data inhabitants
- Purescript: How to read a string from stdin and save it?
- Usecase of Variants in Purescript/Haskell
- PureScript - Splitting Array of Positive and Negative Numbers into Tuple of 2 Arrays of Positive and Negative Numbers
- Getting the date of the next day in PureScript
- PureScript FFI to mocha
- Can I always replace do ... pure ... with ado ... in ... in Purescript?
- How to chain actions in purescript (or maybe defer action after rendering)
- Ascii color prefixes in PureScript doesn't work
- PureScript. Argument list lengths differ in declaration
- Standard unicode operators in purescript
- Compiler can't infer type while using Newtype class Constraint purescript
- Applicative functors and records in purescript
- How to have row without particular field as function param
- How do you create an Effect in Purescript directly via its type constructor?
- New Show instance for existing type