module Bergamot.Search exposing (Search, map, apply, andThen, pure, fail, yield, interleave, one) type SearchStep a = Empty | Found a (Search a) | Yield (Search a) type alias Search a = () -> SearchStep a map : (a -> b) -> Search a -> Search b map f s () = case s () of Empty -> Empty Found a sp -> Found (f a) (map f sp) Yield sp -> Yield (map f sp) apply : Search a -> Search (a -> b) -> Search b apply sa sf () = case sf () of Empty -> Empty Found f sfp -> interleave (map f sa) (apply sa sfp) () Yield sfp -> Yield (apply sa sfp) andThen : (a -> Search b) -> Search a -> Search b andThen f sa () = case sa () of Empty -> Empty Found a sap -> interleave (f a) (andThen f sap) () Yield sap -> Yield (andThen f sap) pure : a -> Search a pure a () = Found a (\() -> Empty) fail : Search a fail () = Empty yield : Search a -> Search a yield s () = Yield s interleave : Search a -> Search a -> Search a interleave s1 s2 () = case s1 () of Empty -> s2 () Found a s1p -> Found a (interleave s2 s1p) Yield s1p -> Yield (interleave s2 s1p) one : Search a -> Maybe (a, Search a) one s = case s () of Empty -> Nothing Found a sp -> Just (a, sp) Yield sp -> one sp