///|
#external
pub type Identity
///|
#external
pub(all) type IReader
///|
pub fn[R, A, B] IReader::map(ab : (R) -> A, bc : (A) -> B) -> (R) -> B {
fn(a) { a |> ab |> bc }
}
///|
pub fn[R, A, B] IReader::chain(ab : (R) -> A, bc : (A) -> (R) -> B) -> (R) -> B {
fn(a) { (a |> ab |> bc)(a) }
}
///|
pub fn[N, A] constant(a : A) -> (N) -> A {
fn(_n) { a }
}
///|
pub fn[N, A] const_identity(_n : N) -> (A) -> A {
identity
}
///|
pub fn[I : Show] constant_as_show(a : I) -> &Show {
a
}
///|
pub fn[N, N2, A] constant_2(a : A) -> (N, N2) -> A {
fn(_n, _n2) { a }
}
///|
pub fn[N, A] panic_with(_n : N) -> A {
panic()
}
///|
pub fn[A] constant_0(a : A) -> () -> A {
fn() { a }
}
///|
pub fn[A, E : Error] raise_exn(a : E) -> A raise E {
raise a
}
///|
pub fn[R, A, E : Error] constant_exn(a : E) -> (R) -> A raise E {
fn(_r) { raise a }
}
///|
pub fn[A, E : Error] constant_exn_0(a : E) -> () -> A raise E {
fn() { raise a }
}
///|
pub fn[A] constant_none() -> A? {
None
}
///|
pub fn[R, A] constant_from_lazy(a : Lazy[A]) -> (R) -> A {
fn(_r) { a.get() }
}
///|
pub fn[A] constant_0_from_lazy(a : Lazy[A]) -> () -> A {
fn() { a.get() }
}
///|
pub fn[A] const_empty_string(_arg : A) -> String {
""
}
///|
pub fn[A] const_zero(_arg : A) -> Int {
0
}
///|
pub fn[A] const_one(_arg : A) -> Int {
1
}
///|
pub fn[A] const_true(_arg : A) -> Bool {
true
}
///|
pub fn[A] const_false(_a : A) -> Bool {
false
}
///|
pub fn[A, B] const_empty_array(_a : A) -> Array[B] {
[]
}
///|
pub fn[R, A] lift_arg(f : () -> A) -> (R) -> A {
fn(_) { f() }
}
///|
pub fn[R, R2, A] lift_arg_0_2(f : () -> A) -> (R, R2) -> A {
fn(_, _) { f() }
}
///|
pub fn[R, R2, A] lift_arg_2(f : (R) -> A) -> (R, R2) -> A {
fn(r, _) { f(r) }
}
///|
pub fn[R, A, E : Error] lift_exn(f : (R) -> A) -> (R) -> A raise E {
fn(r) { f(r) }
}
///|
pub fn[A, E : Error] lift_exn_0(f : () -> A) -> () -> A raise E {
fn() { f() }
}
// ///|
// pub fn const_unit[A](_ : A) -> Unit {
// }
///|
pub fn[A] const_unit(_ : A) -> Unit = "%ignore"
///|
pub fn const_unit_0() -> Unit {
}
///|
pub fn[A, B] ignore2(_a : A, _b : B) -> Unit {
}
///|
pub fn[A : Eq] curried_eq(a : A) -> (A) -> Bool {
curried_first(A::op_equal, a)
}
///|
pub fn[A : Eq] curried_eq_not(a : A) -> (A) -> Bool {
curried_not(A::op_equal, a)
// fn(b) { a != b }
}
///|
pub fn[A : Eq] curried_one_of(a : Many[A]) -> (A) -> Bool {
curried_second(Many::contains, a)
// fn(b) { (a.contains(b)) }
}
///|
pub fn[A : Eq] curried_one_of_not(a : Many[A]) -> (A) -> Bool {
curried_not(Many::contains, a)
// fn(b) { not(a.contains(b)) }
}
///|
pub fn[A : Semigroup] curried_add_pre(a : A) -> (A) -> A {
curried_second(A::op_add, a)
}
///|
pub fn[A : Semigroup] curried_add(a : A) -> (A) -> A {
curried_first(A::op_add, a)
}
///|
test "curray_add" {
inspect(
["1", "2"].map(curried_add("r")),
content=
#|["1r", "2r"]
,
)
inspect(
["1", "2"].map(curried_add_pre("l")),
content=
#|["l1", "l2"]
,
)
}
///|
pub fn[A, B] curried_tuple_snd(a : A) -> (B) -> (B, A) {
curried_first(@tuple.pair, a)
// fn(b) { (b, a) }
}
///|
/// Map a function over the second element of a tuple.
///
/// # Example
/// ```
/// test "Tuple::map_snd" {
/// let tuple = (1, 2)
/// let mapped = @tuple.map_snd(fn(x : Int) -> Int { x + 1 }, tuple)
/// assert_eq(mapped, (1, 3))
/// }
/// ```
pub fn[T, U, V] map_snd(f : (T) -> U, tuple : (V, T)) -> (V, U) {
(tuple.0, f(tuple.1))
}
///|
/// Map a function over the first element of a tuple.
///
/// # Example
/// ```
/// test "Tuple::map_fst" {
/// let tuple = (1, 2)
/// let mapped = @tuple.map_fst(fn(x : Int) -> Int { x + 1 }, tuple)
/// assert_eq(mapped, (2, 2))
/// }
/// ```
pub fn[T, U, V] map_fst(f : (T) -> U, tuple : (T, V)) -> (U, V) {
(f(tuple.0), tuple.1)
}
///|
pub fn[T, U, V] curried_tuple_map_fst(f : (T) -> U) -> ((T, V)) -> (U, V) {
curried_second(map_fst, f)
// fn(t) { (f(t.0), t.1) }
}
///|
pub fn[T, U, V] curried_tuple_map_snd(f : (T) -> U) -> ((V, T)) -> (V, U) {
curried_second(map_snd, f)
// fn(t) { (f(t.0), t.1) }
}
///|
pub fn[A, B] curried_tuple_fst(a : A) -> (B) -> (A, B) {
curried_second(@tuple.pair, a)
// fn(b) { (a, b) }
}
///|
pub fn[A, B] Identity::ap(ab : (A) -> B, a : A) -> B {
ab(a)
}
///|
pub fn[A, B, E : Error] Identity::ap_exn(
ab : (A) -> B raise E,
a : A
) -> B raise E {
ab(a)
}
///|
pub fn[A, B] Identity::map(a : A, f : (A) -> B) -> B {
a |> f
}
///|
pub fn[A, B] Identity::tap(a : A, f : (A) -> B) -> A {
a |> f |> ignore
a
}
///|
pub fn[A, B] curried_apply(a : A) -> ((A) -> B) -> B {
curried_first(Identity::ap, a)
}
///|
pub fn[A, B, E : Error] curried_apply_exn(
a : A
) -> ((A) -> B raise E) -> B raise E {
fn(f) { f(a) }
}
///|
pub fn[A, B] curried_apply_rev(a : (A) -> B) -> (A) -> B {
curried_second(Identity::ap, a)
}
///|
pub fn[A : Compare] curried_maximum(a : A) -> (A) -> A {
curried_second(@math.maximum, a)
}
///|
pub fn[A : Compare] curried_minimum(a : A) -> (A) -> A {
curried_second(@math.minimum, a)
}
///|
test "curried_compare" {
assert_eq(curried_maximum(1)(2), 2)
assert_eq(curried_minimum(1)(2), 1)
}
// ///|
// pub fn identity[A](a : A) -> A {
// a
// }
///|
pub fn[A] identity(a : A) -> A {
a
}
///|
pub fn[A, B] __unsafe_cast(a : A) -> B = "%identity"
///|
pub fn[A, B] is_identity(a : (A) -> B) -> Bool {
unsafe_is(identity, a)
}
///|
fn tests() -> Unit raise Error {
assert_true(is_identity(identity))
assert_false(is_identity(__unsafe_cast))
assert_false(is_identity(const_true))
assert_true(is_identity(const_identity(())))
}
///|
test "is_identity" {
tests()
}
///|
pub fn[A, B, C, D] __unsafe_cast_arrow(a : (A) -> C) -> (B) -> D = "%identity"
///|
pub fn[A : Eq] eq(x : A, y : A) -> Bool {
A::op_equal(x, y)
}
///|
pub fn[A : Eq] not_eq(x : A, y : A) -> Bool {
not(x == y)
}
///|
pub fn[A] check_is(a : A, b : A) -> Bool = "%refeq"
///|
pub fn[A, B] unsafe_is(a : A, b : B) -> Bool = "%refeq"
// {
// physical_equal(a, b)
// }
///|
pub fn[A] is_not(a : A, b : A) -> Bool {
not(check_is(a, b))
}
///|
pub fn[A] curried_is(a : A) -> (A) -> Bool {
curried_second(check_is, a)
}
///|
pub fn[A] curried_is_not(a : A) -> (A) -> Bool {
curried_not(check_is, a)
}