diff --git a/sketching/september_2025/hkt/functor.dm b/sketching/september_2025/hkt/functor.dm new file mode 100644 index 0000000..34b49d0 --- /dev/null +++ b/sketching/september_2025/hkt/functor.dm @@ -0,0 +1,204 @@ +pub trait Functor[*T] + fn map(ftu: fn (t: &*T) -> U) -> Self +end + +pub trait Functor[*L -> *R] + fn mapLeft(flr: fn (l: &*L) -> *R) -> Self<*L, *R> +end + +pub enum Option + Some(T), + None +end + +pub enum Either + Left(L), + Right(R) +end + +pub inst Functor[*T] for Option + impl fn map(ftu: fn (t: T) -> U) -> Self + if self is Some(t) then + Some(ftu(t)) + else + None + end + end +end + +pub inst Functor[*T] for Either<_, *T> + impl fn map(ftu: fn (t: *T) -> U) -> Self + if self is Right(t) then + Right(ftu(t)) + else + self + end + end +end + +pub inst Functor[*L -> *R] for Either + impl fn mapLeft(flr: fn (l: *L) -> *R) -> Self<*L, *R> + if self is Left(l) then + Right(flr(l)) + else + self + end + end +end + +pub trait Monad[*T] + static fn lift(t: *T) -> Self<*T> + fn flatMap(f: fn (t: *T) -> Self) -> Self +end + +pub trait Default + static fn default() -> Self +end + +pub trait Empty[*T] where *T has Default + static fn empty() -> Self<*T> +end + +pub trait Semigroup[*T] + fn concat(other: &Self<*T>) -> Self<&*T> + cons fn consConcat(other: Self<*T>) -> Self<*T> +end + +pub int Iterable + fn iter() -> Iterator + cons fn consIter() -> ConsIterator +end + +pub int Iterator + fn next() -> Option<&T> + fn withIndex() -> Iterator> +end + +pub int ConsIterator + fn next() -> Option + fn withIndex() -> Iterator> +end + +pub int List : Iterable req Monad, Functor, Semigroup, Empty + fn add(t: T) -> Void +end + +pub inst Functor[*T] for List<*T> where *T has Default + impl fn map(ftu: (t: *T) -> U) -> Self + let mut result: Self = Self::empty() + for t in self do + result += Self::lift(ftu(t)) + end + result + end +end + +pub class ArrayList : List + + let init: fn () -> T // ?: sugar for Option T> + let capacity: USize + let mut ts: Array + let count: USize = 0 + + pub ctor(startCapacity: USize = 10, init: fn () -> T = Default::default) where T has Default + := init + capacity = startCapacity // ?= sugar for Some(expr) + ts = array(startCapacity, init) + end + + pub ctor(init: fn () -> T, startCapacity: USize = 10) + := init + capacity = startCapacity + ts = array(startCapacity, init) + end + + impl fn iter() -> Iterator + todo() + end + + impl fn add(t: T) -> Void + ts[count] = t + count++ + if count == capacity then + resize() + end + end + + fn resize() -> Void + let oldTs = mem::take(&ts, array(capacity * 2, init)) + for (i, t) in oldTs.consIter().withIndex() do + ts[i] = t + end + end + +end + +pub inst Empty[*T] for ArrayList<*T> + where *T has Default + impl static fn empty() -> List<*T> = Self() +end + +pub inst Semigroup[*T] for ArrayList<*T> + where *T has Default + impl fn concat(other: List<*T>) -> List<*T> + let result = Self() + for t in self do + result.add(t) + end + for t in other do + result.add(t) + end + result + end +end + +pub inst Monad[*T] for ArrayList<*T> + where T has Default + impl static fn lift(t: *T) -> List<*T> + let result: List<*T> = Self() + result.add(t) + result + end + + impl fn flatMap(f: fn (t: *T) -> List) -> List + let result: List = Self() + for t in self do + for u in f(t) do + result.add(u) + end + end + result + end +end + +pub mod std::core + + pub mod mem + pub native fn take(target: &T, replacement: T) -> T + end + + pub native fn array(capacity: USize, init: fn () -> T) -> Array + + pub native fn array(capacity: USize) -> Array where T has Default + + pub fn list(...items: Array) -> List where T has Default + let result = ArrayList(items.capacity(), Default[T]::default) + for item in items.consIter() do + result.add(item) + end + result + end + +end + +// other file +use std::collections::List +use std::hkt::{Functor[List], Monad[List]} + +fn main() + let someNums: List = [1, 2, 3, 4, 5] + let plusOnes = someNums.map { it + 1 } + println plusOnes // 2, 3, 4, 5, 6 + let twoOfEach = someNums.flatMap { [it, it] } + println twoOfEach // 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 +end \ No newline at end of file