// Generated by ReScript, PLEASE EDIT WITH CARE
'use strict';

var Curry = require("bs-platform/lib/js/curry.js");
var Pervasives = require("bs-platform/lib/js/pervasives.js");
var ListH$OptolithClient = require("./ListH.bs.js");
var Function$OptolithClient = require("./Function.bs.js");

function fromLeft(def, x) {
  if (x.TAG) {
    return def;
  } else {
    return x._0;
  }
}

function fromRight(def, x) {
  if (x.TAG) {
    return x._0;
  } else {
    return def;
  }
}

function fromEither(x) {
  return x._0;
}

function fromLeft$prime(x) {
  if (x.TAG) {
    return Pervasives.invalid_arg("fromLeft': Cannot extract a Left value out of a Right");
  } else {
    return x._0;
  }
}

function fromRight$prime(x) {
  if (x.TAG) {
    return x._0;
  } else {
    return Pervasives.invalid_arg("fromLeft': Cannot extract a Right value out of a Left");
  }
}

function eitherToMaybe(x) {
  if (x.TAG) {
    return /* Just */{
            _0: x._0
          };
  } else {
    return /* Nothing */0;
  }
}

function maybeToEither(left, x) {
  if (x) {
    return {
            TAG: /* Right */1,
            _0: x._0
          };
  } else {
    return {
            TAG: /* Left */0,
            _0: left
          };
  }
}

function maybeToEither$prime(left, x) {
  if (x) {
    return {
            TAG: /* Right */1,
            _0: x._0
          };
  } else {
    return {
            TAG: /* Left */0,
            _0: Curry._1(left, undefined)
          };
  }
}

var Extra = {
  fromLeft: fromLeft,
  fromRight: fromRight,
  fromEither: fromEither,
  fromLeft$prime: fromLeft$prime,
  fromRight$prime: fromRight$prime,
  eitherToMaybe: eitherToMaybe,
  maybeToEither: maybeToEither,
  maybeToEither$prime: maybeToEither$prime
};

function $less$$great(f, x) {
  if (x.TAG) {
    return {
            TAG: /* Right */1,
            _0: Curry._1(f, x._0)
          };
  } else {
    return {
            TAG: /* Left */0,
            _0: x._0
          };
  }
}

var Functor = {
  $less$$great: $less$$great
};

function bimap(fLeft, fRight, x) {
  if (x.TAG) {
    return {
            TAG: /* Right */1,
            _0: Curry._1(fRight, x._0)
          };
  } else {
    return {
            TAG: /* Left */0,
            _0: Curry._1(fLeft, x._0)
          };
  }
}

function first(f, x) {
  if (x.TAG) {
    return {
            TAG: /* Right */1,
            _0: x._0
          };
  } else {
    return {
            TAG: /* Left */0,
            _0: Curry._1(f, x._0)
          };
  }
}

var Bifunctor = {
  bimap: bimap,
  first: first,
  second: $less$$great
};

function $less$star$great(f, x) {
  if (f.TAG) {
    return $less$$great(f._0, x);
  } else {
    return {
            TAG: /* Left */0,
            _0: f._0
          };
  }
}

var Applicative = {
  $less$star$great: $less$star$great
};

function $great$great$eq(x, f) {
  if (x.TAG) {
    return Curry._1(f, x._0);
  } else {
    return {
            TAG: /* Left */0,
            _0: x._0
          };
  }
}

function $eq$less$less(f, mx) {
  return $great$great$eq(mx, f);
}

function $great$great(x, y) {
  return $great$great$eq(x, (function (param) {
                return Function$OptolithClient.$$const(y, param);
              }));
}

function $great$eq$great(f, g, x) {
  return $great$great$eq(Curry._1(f, x), g);
}

function join(x) {
  return $great$great$eq(x, Function$OptolithClient.id);
}

function liftM2(f, mx, my) {
  return $great$great$eq(mx, (function (x) {
                return $less$$great(Curry._1(f, x), my);
              }));
}

function liftM3(f, mx, my, mz) {
  return $great$great$eq(mx, (function (x) {
                return $great$great$eq(my, (function (y) {
                              return $less$$great(Curry._2(f, x, y), mz);
                            }));
              }));
}

function liftM4(f, mx, my, mz, ma) {
  return $great$great$eq(mx, (function (x) {
                return $great$great$eq(my, (function (y) {
                              return $great$great$eq(mz, (function (z) {
                                            return $less$$great(Curry._3(f, x, y, z), ma);
                                          }));
                            }));
              }));
}

var Monad = {
  $great$great$eq: $great$great$eq,
  $eq$less$less: $eq$less$less,
  $great$great: $great$great,
  $great$eq$great: $great$eq$great,
  join: join,
  liftM2: liftM2,
  liftM3: liftM3,
  liftM4: liftM4
};

function foldr(f, init, mx) {
  if (mx.TAG) {
    return Curry._2(f, mx._0, init);
  } else {
    return init;
  }
}

function foldl(f, init, mx) {
  if (mx.TAG) {
    return Curry._2(f, init, mx._0);
  } else {
    return init;
  }
}

function toList(mx) {
  if (mx.TAG) {
    return {
            hd: mx._0,
            tl: /* [] */0
          };
  } else {
    return /* [] */0;
  }
}

function length(mx) {
  if (mx.TAG) {
    return 1;
  } else {
    return 0;
  }
}

function elem(e, mx) {
  if (mx.TAG) {
    return e === mx._0;
  } else {
    return false;
  }
}

function sum(mx) {
  if (mx.TAG) {
    return mx._0;
  } else {
    return 0;
  }
}

function product(mx) {
  if (mx.TAG) {
    return mx._0;
  } else {
    return 1;
  }
}

function concat(mxs) {
  if (mxs.TAG) {
    return mxs._0;
  } else {
    return /* [] */0;
  }
}

function concatMap(f, mx) {
  if (mx.TAG) {
    return Curry._1(f, mx._0);
  } else {
    return /* [] */0;
  }
}

function con(mx) {
  if (mx.TAG) {
    return mx._0;
  } else {
    return true;
  }
}

function dis(mx) {
  if (mx.TAG) {
    return mx._0;
  } else {
    return false;
  }
}

function any(pred, mx) {
  if (mx.TAG) {
    return Curry._1(pred, mx._0);
  } else {
    return false;
  }
}

function all(pred, mx) {
  if (mx.TAG) {
    return Curry._1(pred, mx._0);
  } else {
    return true;
  }
}

function notElem(e, mx) {
  return !elem(e, mx);
}

function find(pred, mx) {
  if (!mx.TAG) {
    return /* Nothing */0;
  }
  var x = mx._0;
  if (Curry._1(pred, x)) {
    return /* Just */{
            _0: x
          };
  } else {
    return /* Nothing */0;
  }
}

var Foldable = {
  foldr: foldr,
  foldl: foldl,
  toList: toList,
  length: length,
  elem: elem,
  sum: sum,
  product: product,
  concat: concat,
  concatMap: concatMap,
  con: con,
  dis: dis,
  any: any,
  all: all,
  notElem: notElem,
  find: find
};

function either(fLeft, fRight, x) {
  if (x.TAG) {
    return Curry._1(fRight, x._0);
  } else {
    return Curry._1(fLeft, x._0);
  }
}

function lefts(xs) {
  return ListH$OptolithClient.Foldable.foldr((function (x, acc) {
                if (x.TAG) {
                  return acc;
                } else {
                  return {
                          hd: x._0,
                          tl: acc
                        };
                }
              }), /* [] */0, xs);
}

function rights(xs) {
  return ListH$OptolithClient.Foldable.foldr((function (x, acc) {
                if (x.TAG) {
                  return {
                          hd: x._0,
                          tl: acc
                        };
                } else {
                  return acc;
                }
              }), /* [] */0, xs);
}

function partitionEithers(xs) {
  return ListH$OptolithClient.Foldable.foldr((function (x, param) {
                var rs = param[1];
                var ls = param[0];
                if (x.TAG) {
                  return [
                          ls,
                          {
                            hd: x._0,
                            tl: rs
                          }
                        ];
                } else {
                  return [
                          {
                            hd: x._0,
                            tl: ls
                          },
                          rs
                        ];
                }
              }), [
              /* [] */0,
              /* [] */0
            ], xs);
}

exports.Extra = Extra;
exports.Functor = Functor;
exports.Bifunctor = Bifunctor;
exports.Applicative = Applicative;
exports.Monad = Monad;
exports.Foldable = Foldable;
exports.either = either;
exports.lefts = lefts;
exports.rights = rights;
exports.partitionEithers = partitionEithers;
/* No side effect */
