From cfe24aa107f704c1b8cdc3de227fc5de89553b51 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Sun, 28 Sep 2025 12:34:29 -0500 Subject: [PATCH] More sketching of functor, list, and related. --- sketching/september_2025/hkt/functor.dm | 200 ++++++++++++++---------- 1 file changed, 116 insertions(+), 84 deletions(-) diff --git a/sketching/september_2025/hkt/functor.dm b/sketching/september_2025/hkt/functor.dm index 34b49d0..236baef 100644 --- a/sketching/september_2025/hkt/functor.dm +++ b/sketching/september_2025/hkt/functor.dm @@ -16,8 +16,8 @@ pub enum Either Right(R) end -pub inst Functor[*T] for Option - impl fn map(ftu: fn (t: T) -> U) -> Self +pub impl Functor[*T] for Option + fn map(ftu: fn (t: &*T) -> U) -> Self if self is Some(t) then Some(ftu(t)) else @@ -26,20 +26,20 @@ pub inst Functor[*T] for Option end end -pub inst Functor[*T] for Either<_, *T> - impl fn map(ftu: fn (t: *T) -> U) -> Self +pub impl Functor[*R] for Either<_, *R> + fn map(f: fn (t: &*R) -> U) -> Self<_, U> if self is Right(t) then - Right(ftu(t)) + Right(f(t)) else self end end end -pub inst Functor[*L -> *R] for Either - impl fn mapLeft(flr: fn (l: *L) -> *R) -> Self<*L, *R> +pub impl Functor[*L -> *R] for Either + fn mapLeft(f: fn (l: &*L) -> *R) -> Self<*L, *R> if self is Left(l) then - Right(flr(l)) + Right(f(l)) else self end @@ -48,100 +48,53 @@ end pub trait Monad[*T] static fn lift(t: *T) -> Self<*T> - fn flatMap(f: fn (t: *T) -> Self) -> Self + 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 +pub trait Empty[*T] 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> + type Other<*T> + + fn concat(other: &Other<*T>) -> Self<&*T> + cons fn consConcat(other: Other<*T>) -> Self<*T> end pub int Iterable - fn iter() -> Iterator + fn iter() -> Iterator ref self cons fn consIter() -> ConsIterator end pub int Iterator - fn next() -> Option<&T> - fn withIndex() -> Iterator> + fn next() -> Option<&T ref self> 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 impl Semigroup[*T] for Iterable<*T> + type Other = Iterable<*T> -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() + fn concat(other: &Other<*T>) -> Self<*T> + let result: Self<*T> = ArrayList(count()) for t in self do - result += Self::lift(ftu(t)) + result.add(t) + end + for t in other do + result.add(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() + cons fn consConcat(other: Other<*T>) -> Self<*T> + let result: Self<*T> = ArrayList(count()) for t in self do result.add(t) end @@ -152,18 +105,35 @@ pub inst Semigroup[*T] for ArrayList<*T> 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() +pub int List : Iterable + fn add(t: T) -> Void +end + +pub impl Functor[*T] for List<*T> + fn map(f: (t: &*T) -> U) -> Self + let mut result: Self = ArrayList(count()) + for t in self do + result.add(f(t)) + end + result + end +end + +pub impl Empty[*T] for List<*T> + static fn empty() -> List<*T> = ArrayList() +end + +pub inst Monad[*T] for List<*T> + static fn lift(t: *T) -> List<*T> + let result: List<*T> = ArrayList() result.add(t) result end - impl fn flatMap(f: fn (t: *T) -> List) -> List - let result: List = Self() + fn flatMap(f: fn (t: &*T) -> List) -> List + let result: List = ArrayList(count()) for t in self do - for u in f(t) do + for u in f(t).consIter() do result.add(u) end end @@ -171,6 +141,69 @@ pub inst Monad[*T] for ArrayList<*T> end end +pub class ArrayList : List + + let capacity: USize + let mut ts: Array> + let count: USize = 0 + + pub ctor(startCapacity: USize = 10) + capacity = startCapacity + ts = array(startCapacity, None) + end + + class ArrayListIterator(owner: &ArrayList) /* ref owner (implied by constructor) */ : Iterator + let i: USize = 0 + + impl fn next() -> Option<&T ref self> + if owner.ts[i] is Some(t) then + i++ + Some(t) + else + None + end + end + end + + class ConsArrayListIterator(ts: Array>) : ConsIterator + let i: USize = 0 + + impl fn next() -> Option + if ts[i] is Some then + let wrappedT = mem::take(ts[i], None) + i++ + wrappedT + else + None + end + end + end + + impl fn iter() -> Iterator<&T> ref self + ArrayListIterator(&self) + end + + impl cons fn consIter() -> Iterator + ConsArrayListIterator(mem::take(ts, arrays::empty())) + end + + impl fn add(t: T) -> Void + ts[count] = Some(t) + count++ + if count == capacity then + resize() + end + end + + fn resize() -> Void + let oldTs = mem::take(&ts, array(capacity * 2, None)) + for (i, wrappedT) in oldTs.consIter() do + ts[i] = wrappedT + end + end + +end + pub mod std::core pub mod mem @@ -181,8 +214,8 @@ pub mod std::core 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) + pub fn list(...items: Array) -> List + let result = ArrayList(items.capacity()) for item in items.consIter() do result.add(item) end @@ -191,8 +224,7 @@ pub mod std::core end -// other file -use std::collections::List +// Other file use std::hkt::{Functor[List], Monad[List]} fn main()