[WIP] Personal Utils
fn[A] lor(a : A?, b : A?) -> A?fn to_debug_string(self : String) -> Stringpub(open) trait GetChar {
op_get(Self, Int) -> Char
}fn op_get(self : String, idx : Int) -> Charpub(open) trait GetUtf16CodePoint : GetChar + Length {
get_utf16(Self, Int) -> Utf16CodePoint = _
get_utf16_exn(Self, Int) -> Utf16CodePoint raise GetUtf16CharError = _
}pub(open) trait JoinToString {
join_all(Self) -> String
}pub(open) trait Length {
length(Self) -> Int
is_empty(Self) -> Bool = _
}fn length(self : String) -> Intfn[A] length(self : FixedArray[A]) -> Intfn length(self : Bytes) -> Intfn op_add(_x : Unit, _y : Unit) -> Unitfn op_add(_x : Int, _y : Int) -> Intfn op_add(_x : UInt, _y : UInt) -> UIntpub(open) trait Semiring {
zero() -> Self
one() -> Self
op_add(Self, Self) -> Self
op_mul(Self, Self) -> Self
}pub(open) trait ToChar {
to_char(Self) -> Char
}pub(open) trait ToString {
to_string(Self) -> String
}fn to_string(self : Char) -> Stringfn to_string(a : String) -> Stringpub(open) trait Zero {
zero() -> Self
}#external
pub(all) type Applypub(all) type Cursor Intpub(all) type DebugFn[A] () -> Apub(all) enum Either[L, R] {
Left(L)
Right(R)
}pub(all) enum Endianness {
LittleEndian
BigEndian
NetworkEndian
}pub(all) type Foldable[R, A, B] (R, B, (B, A) -> B) -> Bpub(all) type FoldableWithIndex[R, A, B] (R, B, (Int, B, A) -> B) -> Bfn[R, A, B] FoldableWithIndex::inner(self : FoldableWithIndex[R, A, B]) -> ((R, B, (Int, B, A) -> B) -> B)pub(all) enum GetUtf16CharError {
OutOfRange(Int, Int)
InvalidStringHighSurrogate
InvalidStringLowSurrogate
UnreachableCode(Int)
}#external
pub(all) type IReader#external
pub type Identitypub(all) type Lazy[A] () -> Apub(all) type Many[A] FixedArray[A]pub type NonEmptyString Stringpub(all) enum Ordering {
Less
Greater
Eq
}pub(all) type Reader[R, A] (R) -> Atest "Reader::memo_ignore_arg" {
let counter = StringBuilder::new()
let reader = Reader(fn(x : Int) {
counter.write_string("computed\n")
42
})
let memoized = Reader::memo_ignore_arg(reader)
inspect!(memoized.read(1), content="42")
inspect!(memoized.read(2), content="42")
inspect!(counter.to_string(), content="computed\n")
}pub(all) struct Sequence[R, I, A] {
make : (Int, A) -> R
op_get : (R, I) -> A
op_set : (R, I, A) -> Unit
}pub(all) type State[S, A] (S) -> (A, S)pub(all) enum Utf16CodePoint {
BMP(Char)
HighSurrogate(Char)
LowSurrogate(Char)
}fn[T, U, V, W] curried_2(f : (T, U, W) -> V, y : U, z : W) -> ((T) -> V)fn[A, B, E : Error] curried_apply_exn(a : A) -> (((A) -> B raise E) -> B raise E)fn[T, U, V] curried_first(f : (T, U) -> V, y : U) -> ((T) -> V)let add = fn(x : Int, y : String) -> String { x.to_string() + y }
let curried_add = @lib.curried_first(add, "str")
assert_eq!(curried_add(1), "1str")fn[T, U, V] curried_second(f : (T, U) -> V, x : T) -> ((U) -> V)let add = fn(x : Int, y : String) -> String { x.to_string() + y }
let curried_add = @lib.curried_second(add, 1)
assert_eq!(curried_add("str"), "1str")fn[A, B, C, D, E] curry_3(f : (A, B, C, D) -> E) -> ((A) -> ((B) -> ((C) -> ((D) -> E))))fn[A, B, C, D, E, F] curry_4(f : (A, B, C, D, E) -> F) -> ((A) -> ((B) -> ((C) -> ((D) -> ((E) -> F)))))fn digit_char_2_int(char : Char) -> Inttest "digit_2_int" {
inspect!(digit_2_int('5'), content="5")
inspect!(digit_2_int('0'), content="0")
}
test "panic digit_2_int/invalid_char" {
let _ = digit_2_int('a')
}fn[T : GetUtf16CodePoint + GetChar + Length] get_utf16_char_at(input : T, idx_word : Int) -> Utf16CodePointlet str = "\u{6708}\u{1f430}\u{5154}" // 月🐰兔
let mut i = 0
while i < str.length() {
let (ch, ty) = get_utf16_char_at(str, i)
println(ch)
// advance by 2 words on a surrogate pair
i += if ty != Utf16WordType::BMP { 1 } else { 2 }
}fn int_be_from_bytes(bytes : FixedArray[Byte], offset : Int) -> Intfn int_from_bytes(bytes : FixedArray[Byte], offset : Int, endian : Endianness, source~ : SourceLoc = _) -> Intfn int_into_bytes_be(v : Int, target : FixedArray[Byte], offset : Int) -> Unitfn int_into_bytes_le(v : Int, target : FixedArray[Byte], offset : Int) -> Unitfn int_le_from_bytes(bytes : FixedArray[Byte], offset : Int) -> Intfn int_to_bytes_be(v : Int) -> FixedArray[Byte]fn int_to_bytes_le(v : Int) -> FixedArray[Byte]fn[A : WriteToStringBuilder + Show, B : WriteToStringBuilder + Show, C : WriteToStringBuilder + Show] join3(a : A, b : B, c : C) -> Stringfn[T, U, V] map_fst(f : (T) -> U, tuple : (T, V)) -> (U, V)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))
}fn[T, U, V] map_snd(f : (T) -> U, tuple : (V, T)) -> (V, U)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))
}test "alt" {
let a : Int? = Some(1)
let b : Int? = Some(2)
inspect!(@lib.or(a, b), content="Some(1)")
let c : Int? = None
inspect!(@lib.or(c, b), content="Some(2)")
}fn to_hex_string(num : Int, upper_case~ : Bool = ..) -> Stringtest "to_hex_string" {
// Basic conversion
inspect!(to_hex_string(255), content="ff")
inspect!(to_hex_string(255, upper_case=true), content="FF")
// Zero case
inspect!(to_hex_string(0), content="0")
// Larger numbers
inspect!(to_hex_string(0x1234), content="1234")
}
test "panic to_hex_string/negative" {
let _ = to_hex_string(-1)
}