Skip to content

Instantly share code, notes, and snippets.

@cideM
Created March 6, 2020 18:43
Show Gist options
  • Save cideM/bd66c7c16f3b91bcdbbd4f2afe87a24f to your computer and use it in GitHub Desktop.
Save cideM/bd66c7c16f3b91bcdbbd4f2afe87a24f to your computer and use it in GitHub Desktop.
Working through interesting code for breadth first traversal from a blog post
[Link to Breadth First series](https://doisinkidney.com/posts/2018-03-17-rose-trees-breadth-first.html)
> data Tree a = Node
> { root :: a
> , forest :: Forest a
> }
>
> type Forest a = [Tree a]
> breadthFirst :: Forest a -> [a]
> breadthFirst ts =
> let foo = foldr f b ts
> in foo []
> where
> f :: Tree a -> ([Forest a] -> [a]) -> [Forest a] -> [a]
> f (Node x xs) fn xs' = x : fn (xs : xs')
> b :: [Forest a] -> [a]
> b [] = []
> b qs =
> let foo = foldl (foldr f) b qs
> in foo []
> foo as = foldr f b as 5
> where
> f x fn y = (fn x) + y
> b n = n * 3
Output is `foo [1,2,3]`
f is called with 3 and b (the first accumulator). It returs a new
accumulator, a partially applied function, which still needs its y.
Now f is called with 2 and the accumulator from above. Just like before,
it returns a partially applied function. In this case a function that
still needs the y. The interesting bit is that `fn x` isn't just `b`, it's
the partially applied function from before, which also includes `b`. We're
building a chain of function application here.
((3 * 3) + 2 + 1) + 5
This is what happens when applying foo to [1,2,3]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment