//@NO-IMPLICIT-PRELUDE //! Implementation of the `Foldable` type let { Bool, Option } = import! std.types let { Semigroup, append } = import! std.semigroup let { Monoid, empty } = import! std.monoid let { wrap } = import! std.applicative let { Monad, flat_map } = import! std.monad let { Eq, (==) } = import! std.cmp /// Operations over a data structure that can be folded which means that a functions gets called on /// each element to reduce the structure to a single value (`Array`, `List` and `Map` are all `Foldable`) #[implicit] type Foldable (f : Type -> Type) = { foldr : forall a b . (a -> b -> b) -> b -> f a -> b, foldl : forall a b . (b -> a -> b) -> b -> f a -> b } let foldr ?fold : forall a b . [Foldable f] -> (a -> b -> b) -> b -> f a -> b = fold.foldr let foldl ?fold : forall a b . [Foldable f] -> (b -> a -> b) -> b -> f a -> b = fold.foldl let concat : [Foldable t] -> [Monoid m] -> t m -> m = foldr append empty let concat_map f : [Foldable t] -> [Monoid m] -> (a -> m) -> t a -> m = foldr (\x -> append (f x)) empty let fold_m ?fold ?monad f z : [Foldable t] -> [Monad m] -> (a -> b -> m a) -> a -> t b -> m a = foldl (\acc y -> flat_map (\x -> f x y) acc) (wrap z) let find ?fold pred : [Foldable t] -> (a -> Bool) -> t a -> Option a = let go acc next = match acc with | None -> if pred next then Some next else None | Some _ -> acc fold.foldl go None let find_map ?fold pred : [Foldable t] -> (a -> Option b) -> t a -> Option b = let go acc next = match acc with | None -> pred next | Some _ -> acc fold.foldl go None let all pred : [Foldable t] -> (a -> Bool) -> t a -> Bool = foldl (\acc x -> acc && pred x) True let any pred : [Foldable t] -> (a -> Bool) -> t a -> Bool = foldl (\acc x -> acc || pred x) False let elem x : [Foldable t] -> [Eq a] -> a -> t a -> Bool = any ((==) x) let count : [Foldable t] -> t a -> Int = foldl (\acc _ -> acc #Int+ 1) 0 { Foldable, foldr, foldl, fold_m, concat, concat_map, find, find_map, all, any, elem, count, }