//@NO-IMPLICIT-PRELUDE
//! A type that can represent the abscence of a value
let { error } = import! std.prim
let { Semigroup } = import! std.semigroup
let { Monoid } = import! std.monoid
let { Eq, Ord, Ordering } = import! std.cmp
let { Functor } = import! std.functor
let { Monad } = import! std.monad
let { Traversable } = import! std.traversable
let { Applicative } = import! std.applicative
let { Alternative } = import! std.alternative
let { Show } = import! std.show
let { Bool } = import! std.bool
let { Option, Result } = import! std.types
let string @ { ? } = import! std.string
let { Foldable } = import! std.foldable
let { (<>) } = import! std.semigroup
let unwrap opt : Option a -> a =
match opt with
| Some x -> x
| None -> error "Option was None"
let unwrap_or default opt : a -> Option a -> a =
match opt with
| Some x -> x
| None -> default
let to_result err opt : e -> Option a -> Result e a =
match opt with
| Some x -> Ok x
| None -> Err err
let former =
let semigroup : Semigroup (Option a) = {
append = \l r ->
match l with
| Some x -> Some x
| None -> r,
}
let monoid : Monoid (Option a) = {
semigroup = semigroup,
empty = None,
}
{ semigroup, monoid }
let latter =
let semigroup : Semigroup (Option a) = {
append = \l r ->
match r with
| Some x -> Some x
| None -> l,
}
let monoid : Monoid (Option a) = {
semigroup = semigroup,
empty = None,
}
{ semigroup, monoid }
let semigroup a : Semigroup a -> Semigroup (Option a) = {
append = \l r ->
match (l, r) with
| (Some x, Some y) -> Some (a.append x y)
| (Some _, None) -> l
| (None, Some _) -> r
| (None, None) -> None,
}
let monoid a : Semigroup a -> Monoid (Option a) = {
semigroup = semigroup a,
empty = None,
}
let eq ?a : [Eq a] -> Eq (Option a) = {
(==) = \l r ->
match (l, r) with
| (Some l_val, Some r_val) -> a.(==) l_val r_val
| (None, None) -> True
| _ -> False,
}
let ord ?a : [Ord a] -> Ord (Option a) = {
eq = eq,
compare = \l r ->
match (l, r) with
| (Some l_val, Some r_val) -> a.compare l_val r_val
| (None, Some _) -> LT
| (Some _, None) -> GT
| (None, None) -> EQ,
}
let functor : Functor Option = {
map = \f x ->
match x with
| Some y -> Some (f y)
| None -> None,
}
let applicative : Applicative Option = {
functor = functor,
apply = \f x ->
match (f, x) with
| (Some g, Some y) -> Some (g y)
| _ -> None,
wrap = \x -> Some x,
}
let alternative : Alternative Option = {
applicative = applicative,
empty = None,
or = \x y ->
match x with
| Some _ -> x
| None -> y,
}
let monad : Monad Option = {
applicative = applicative,
flat_map = \f m ->
match m with
| Some x -> f x
| None -> None,
}
let show ?d : [Show a] -> Show (Option a) =
let show o =
match o with
| Some x -> "Some (" <> d.show x <> ")"
| None -> "None"
{ show }
let foldable : Foldable Option = {
foldr = \f z o ->
match o with
| None -> z
| Some x -> f x z,
foldl = \f z o ->
match o with
| None -> z
| Some x -> f z x,
}
let traversable : Traversable Option = {
functor = functor,
foldable = foldable,
traverse = \app f o ->
match o with
| None -> app.wrap None
| Some x -> app.functor.map Some (f x),
}
{
Option,
unwrap,
unwrap_or,
to_result,
semigroup,
monoid,
former,
latter,
eq,
ord,
functor,
applicative,
alternative,
monad,
show,
foldable,
traversable,
}