gluon 0.18.2

A static, type inferred programming language for application embedding
Documentation
//@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,
}