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