Consider the following Python function, which, given the successors of a node, visits them and collects the results. (In practice this logic would form a part of the recursive visit function.)
from typing import Any, Callable, Tuple, List, Set
Node_key = Any
Discovered = Set[Node_key]
Result = Any
def get_successor_results(visit: Callable[[Discovered, Node_key],
Tuple[Discovered, Result]],
successors: List[Node_key],
disc: Discovered) -> List[Result]:
results = []
for succ in successors:
if succ not in disc:
disc, result = visit(disc, succ)
results.append(result)
return results
(For context, this would be part of a df-traverse function which, given a graph and a function combiner :: Node_key -> [Result] -> Result would be equivalent to building the depth-first forest and calling fold-tree combiner on each tree.)
My Question: How would you write
get_successor_resultsin Haskell?
Some ideas:
get-successor-results visit successors disc =
reverse . first . conditional-fold
(\(d, _) node -> not (elem node d))
(cons-next-result visit)
(empty-set, [])
successors
where
cons-next-result visit _@(disc, results) node =
let (disc-new, result) = visit disc node
in (disc-new, result:results)
conditional-fold p folder e xs = case xs of
{[] -> e;
x:xs' -> if p e x then conditional-fold p folder (folder e x) xs'
else conditional-fold p folder e xs'}