Computationwraps a result of a function in a type.
augmentstrips the type, applies a function to the result. The function must wrap the end result in the type again.
combine“joins” two results together.
 and instance of
Computation illustrates it the best.
Failable are a bit “funny” because the
combine works like
or, i.e. they take the first
success x and run with it.
searchAll to work requires a type definition.
searchAll :: Graph v e -> Int Int -> Maybe [Int]
searchAll :: Graph v e -> Int Int -> Failable [Int]
searchAll :: Graph v e -> Int Int -> [[Int]]
How I think about
src == dstis a successful end state. The result is
- Running out of edges in the inner function (
search') is an unsuccessful end state. The result is a string wrapped in
- The first recursive step for
src == u) walks us one step on the way (
- The call to
searchAllreturns a wrapped result (i.e. path(s) from
augmentthis result by sticking
uin front of it (for the list-based
u:on each path, for the others it means dropping the “wrapper type” and calling
(u:)on the actual result), then
- we wrap it all up again.
- Finally we
combineit with the result of a
search'on the other edges. The
combinein the case of lists is concatenation, i.e. we add our list of current results to all other results. For the other two
combineis a “pick first” operation.
- The call to
- The other recursive step for
search'simply looks for results in all remaining edges since the current edge isn’t part of our path.
Now I can go on to read about monads.