squiggle/src/utility/E.re

303 lines
7.8 KiB
ReasonML
Raw Normal View History

open Rationale.Function.Infix;
/* Utils */
module U = {
let isEqual = (a, b) => a == b;
let toA = a => [|a|];
let id = e => e;
};
module O = {
let dimap = (sFn, rFn, e) =>
switch (e) {
| Some(r) => sFn(r)
| None => rFn()
};
();
let fmap = Rationale.Option.fmap;
let bind = Rationale.Option.bind;
let default = Rationale.Option.default;
let isSome = Rationale.Option.isSome;
2020-02-09 18:47:12 +00:00
let isNone = Rationale.Option.isNone;
let toExn = Rationale.Option.toExn;
let some = Rationale.Option.some;
let firstSome = Rationale.Option.firstSome;
let toExt = Rationale.Option.toExn;
let flatApply = (fn, b) =>
Rationale.Option.apply(fn, Some(b)) |> Rationale.Option.flatten;
let toBool = opt =>
switch (opt) {
| Some(_) => true
| _ => false
};
let ffmap = (fn, r) =>
switch (r) {
| Some(sm) => fn(sm)
| _ => None
};
let toString = opt =>
switch (opt) {
| Some(s) => s
| _ => ""
};
let toResult = (error, e) =>
switch (e) {
| Some(r) => Belt.Result.Ok(r)
| None => Error(error)
};
module React = {
let defaultNull = default(ReasonReact.null);
let fmapOrNull = fn => fmap(fn) ||> default(ReasonReact.null);
let flatten = default(ReasonReact.null);
};
};
/* Functions */
module F = {
let apply = (a, e) => a |> e;
let flatten2Callbacks = (fn1, fn2, fnlast) =>
fn1(response1 => fn2(response2 => fnlast(response1, response2)));
let flatten3Callbacks = (fn1, fn2, fn3, fnlast) =>
fn1(response1 =>
fn2(response2 =>
fn3(response3 => fnlast(response1, response2, response3))
)
);
let flatten4Callbacks = (fn1, fn2, fn3, fn4, fnlast) =>
fn1(response1 =>
fn2(response2 =>
fn3(response3 =>
fn4(response4 => fnlast(response1, response2, response3, response4))
)
)
);
};
module Bool = {
type t = bool;
let toString = (t: t) => t ? "TRUE" : "FALSE";
let fromString = str => str == "TRUE" ? true : false;
module O = {
let toBool = opt =>
switch (opt) {
| Some(true) => true
| _ => false
};
};
};
module Float = {
let with2DigitsPrecision = Js.Float.toPrecisionWithPrecision(_, ~digits=2);
let with3DigitsPrecision = Js.Float.toPrecisionWithPrecision(_, ~digits=3);
let toFixed = Js.Float.toFixed;
let toString = Js.Float.toString;
};
module I = {
let increment = n => n + 1;
let decrement = n => n - 1;
let toString = Js.Int.toString;
};
/* R for Result */
module R = {
let result = Rationale.Result.result;
let id = e => e |> result(U.id, U.id);
let fmap = Rationale.Result.fmap;
let bind = Rationale.Result.bind;
2020-02-18 15:50:36 +00:00
let toOption = (e: Belt.Result.t('a, 'b)) =>
switch (e) {
| Ok(r) => Some(r)
| Error(_) => None
};
};
let safe_fn_of_string = (fn, s: string): option('a) =>
2020-02-23 19:40:38 +00:00
try(Some(fn(s))) {
| _ => None
};
module S = {
let safe_float = float_of_string->safe_fn_of_string;
let safe_int = int_of_string->safe_fn_of_string;
let default = (defaultStr, str) => str == "" ? defaultStr : str;
};
module J = {
let toString = Js.Json.decodeString ||> O.default("");
let fromString = Js.Json.string;
let fromNumber = Js.Json.number;
module O = {
let fromString = (str: string) =>
switch (str) {
| "" => None
| _ => Some(Js.Json.string(str))
};
let toString = (str: option('a)) =>
switch (str) {
| Some(str) => Some(str |> (Js.Json.decodeString ||> O.default("")))
| _ => None
};
};
};
module M = {
let format = MomentRe.Moment.format;
let format_standard = "MMM DD, YYYY HH:mm";
let format_simple = "L";
/* TODO: Figure out better name */
let goFormat_simple = MomentRe.Moment.format(format_simple);
let goFormat_standard = MomentRe.Moment.format(format_standard);
let toUtc = MomentRe.momentUtc;
let toJSON = MomentRe.Moment.toJSON;
let momentDefaultFormat = MomentRe.momentDefaultFormat;
};
module JsDate = {
let fromString = Js.Date.fromString;
let now = Js.Date.now;
let make = Js.Date.make;
let valueOf = Js.Date.valueOf;
};
/* List */
module L = {
let fmap = List.map;
2020-03-03 21:30:33 +00:00
let get = Belt.List.get;
let toArray = Array.of_list;
let fmapi = List.mapi;
let concat = List.concat;
let append = List.append;
2020-03-03 21:30:33 +00:00
let drop = Rationale.RList.drop;
let remove = Rationale.RList.remove;
let find = List.find;
let filter = List.filter;
let for_all = List.for_all;
let exists = List.exists;
let sort = List.sort;
let length = List.length;
let filter_opt = Rationale.RList.filter_opt;
let uniqBy = Rationale.RList.uniqBy;
let join = Rationale.RList.join;
let head = Rationale.RList.head;
let uniq = Rationale.RList.uniq;
let flatten = List.flatten;
let last = Rationale.RList.last;
let append = List.append;
let getBy = Belt.List.getBy;
let dropLast = Rationale.RList.dropLast;
let contains = Rationale.RList.contains;
let without = Rationale.RList.without;
let update = Rationale.RList.update;
let iter = List.iter;
let findIndex = Rationale.RList.findIndex;
};
/* A for Array */
module A = {
let fmap = Array.map;
let fmapi = Array.mapi;
let to_list = Array.to_list;
let of_list = Array.of_list;
let length = Array.length;
let append = Array.append;
let empty = [||];
let unsafe_get = Array.unsafe_get;
let get = Belt.Array.get;
let getBy = Belt.Array.getBy;
2020-02-23 19:40:38 +00:00
let last = a => get(a, length(a) - 1);
let first = get(_, 0);
2020-02-13 21:24:47 +00:00
let hasBy = (r, fn) => Belt.Array.getBy(r, fn) |> O.isSome;
let fold_left = Array.fold_left;
let fold_right = Array.fold_right;
let concatMany = Belt.Array.concatMany;
let keepMap = Belt.Array.keepMap;
let stableSortBy = Belt.SortArray.stableSortBy;
2020-02-18 15:50:36 +00:00
let toRanges = (a: array('a)) =>
switch (a |> Belt.Array.length) {
| 0
| 1 => Belt.Result.Error("Must be at least 2 elements")
| n =>
Belt.Array.makeBy(n - 1, r => r)
|> Belt.Array.map(_, index =>
(
Belt.Array.getUnsafe(a, index),
Belt.Array.getUnsafe(a, index + 1),
)
)
|> Rationale.Result.return
};
let asList = (f: list('a) => list('a), r: array('a)) =>
r |> to_list |> f |> of_list;
/* TODO: Is there a better way of doing this? */
let uniq = r => asList(L.uniq, r);
// @todo: Is -1 still the indicator that this is false (as is true with
// @todo: js findIndex)? Wasn't sure.
let findIndex = (e, i) =>
Js.Array.findIndex(e, i)
|> (
r =>
switch (r) {
| (-1) => None
| r => Some(r)
}
);
let filter = (o, e) => Js.Array.filter(o, e);
module O = {
let concatSomes = (optionals: array(option('a))): array('a) =>
optionals
|> Js.Array.filter(Rationale.Option.isSome)
|> Js.Array.map(
Rationale.Option.toExn("Warning: This should not have happened"),
);
let defaultEmpty = (o: option(array('a))): array('a) =>
switch (o) {
| Some(o) => o
| None => [||]
};
};
module R = {
let firstErrorOrOpen =
(results: array(Belt.Result.t('a, 'b)))
: Belt.Result.t(array('a), 'b) => {
let bringErrorUp =
switch (results |> Belt.Array.getBy(_, Belt.Result.isError)) {
| Some(Belt.Result.Error(err)) => Belt.Result.Error(err)
| Some(Belt.Result.Ok(_)) => Belt.Result.Ok(results)
| None => Belt.Result.Ok(results)
};
let forceOpen = (r: array(Belt.Result.t('a, 'b))): array('a) =>
r |> Belt.Array.map(_, r => Belt.Result.getExn(r));
bringErrorUp |> Belt.Result.map(_, forceOpen);
};
};
};
module JsArray = {
let concatSomes = (optionals: Js.Array.t(option('a))): Js.Array.t('a) =>
optionals
|> Js.Array.filter(Rationale.Option.isSome)
|> Js.Array.map(
Rationale.Option.toExn("Warning: This should not have happened"),
);
let filter = Js.Array.filter;
2020-02-26 09:11:06 +00:00
};
let ste = React.string;
2020-03-03 21:30:33 +00:00
let showIf = (cond, comp) => cond ? comp : ReasonReact.null;