Higher order function on a tree¶
Yeah, tree is constructed in such a way, but how do you perform an operation on it?
I set three operations which will help you customize a tree in a simple manner.
They automatically traverse the tree on which it inhabits.
It means they will be implemented in a way that reach all of nodes checking each reference between nodes out.
1. fmap , fmapL ¶
fmap is a bit generalized map operation which can often be called functor
.
Type of functor is
fmap :: Functor f => (a -> b) -> f a -> f b
where first argument is a function which gets a and returns b & second is a set of data type which contains data a with functor instance.
Since I set fmap as a member argument of base node, f a is a set of nodes which can be shown as an object before .fmap.
Note that original functor are performed on an immutable data which mean type a & b are non-relavant. But, this case, since fmap is a member function, type is
fmap :: Functor f => (a -> a') -> f a -> f a'
where a' can be partially modified object.
This allowance of mutableness helps performance faster, but makes side-effects and codes ugly.
On the other hand, fmapL does not have any side effects as it returns lists after a given function is applied.
Its type are
fmapL :: Functor f => (a -> [b]) -> f a -> [b]
2. filter , filterL ¶
filter is a function which accepts a function which will return boolean value.
original type is defined only for list.
filter :: (a -> Bool) -> [a] -> [a]
here type of extended filter was
filter :: (a -> Bool) -> f a -> f a
where f is a set of object.
Keep in mind tree have to be reconstructed after filtering nodes.
For instance, to put it falankly, if a parent node has two child, and it is removed the left two orphans makes quarrel which one should come to a grand parent.
You can filter a parent whose child is just 1, but you cannot filter singleton or a parent more than two children out.
3. foldl foldr ¶
fold is a generalization of above two higher order functions.
But, it shuld be used for the cases where only states are needed and updated during a traverse.
Its type are
foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b
where b is a state
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
where b is a state
Its differece is whether state comes first or second of a given function. Note it does not change how they are traversed on a tree, but each individual application is just slightly different.