51 lines
1 KiB
Nix
51 lines
1 KiB
Nix
{nib, ...}: let
|
|
findFirst = nib.std.findFirst;
|
|
in rec {
|
|
# Res (Result) Monad
|
|
Res = success: value: {
|
|
_success_ = success;
|
|
_value_ = value;
|
|
};
|
|
Ok = Res true;
|
|
Ok' = Ok "ok";
|
|
Err = Res false;
|
|
Err' = Err "err";
|
|
|
|
# Pattern Matching
|
|
isRes = R: builtins.attrNames R == ["_success_" "_value_"];
|
|
isOk' = R: isRes R && R._success_;
|
|
isOk = R:
|
|
assert isRes R || nib.panic.badType "Res" R;
|
|
isOk' R;
|
|
isErr' = R: isRes R && !R._success_;
|
|
isErr = R:
|
|
assert isRes R || nib.panic.badType "Res" R;
|
|
isErr' R;
|
|
|
|
# Unwrap (Monadic Return Operation)
|
|
unwrapRes = f: g: R:
|
|
if isOk R
|
|
then f R._value_
|
|
else g R._value_;
|
|
unwrapOk = unwrapRes (v: v);
|
|
unwrapErr = f: unwrapRes f (v: v);
|
|
|
|
# Map (Monadic Bind Operation)
|
|
mapRes = f: g: unwrapRes (v: Ok (f v)) (v: Err (f v));
|
|
mapOk = f: mapRes f (v: v);
|
|
mapErr = f: mapRes (v: v) f;
|
|
|
|
# Conditionals
|
|
okOr = f: R:
|
|
if isOk R
|
|
then R
|
|
else f R;
|
|
|
|
errOr = f: R:
|
|
if isErr R
|
|
then R
|
|
else f R;
|
|
|
|
# Standard Helpers
|
|
firstErr = findFirst isErr' Ok';
|
|
}
|