diff --git a/sketching/hkt.dm b/sketching/hkt.dm index 3f3065d..71c1a06 100644 --- a/sketching/hkt.dm +++ b/sketching/hkt.dm @@ -1,112 +1,88 @@ -pub hkt Monoid { - identity: T - fn concat(first_item: A, second_item: A): T -} - -pub hkt Monad { - fn map(mapper: fn (item: A): B): T - fn flat_map(mapper: fn (item: A): T): T -} - // Use this one! -pub hkt Identity(a: A) { - fn identity() = a +pub int Unit + +pub hkt Identity { + fn identity() = Self } -pub hkt Monoid(a: A) : Identity(a) { +pub int Addable> { + fn op+(other: T): T +} + +pub hkt Monoid>(a: A) : Identity { fn concat(other: Self) = Self(a + other.a) } -pub hkt Monad1(a: A) { - fn map(mapper: fn (from: A): B) = Self(mapper(a)) - fn flat_map(mapper: fn (from: A): T) = Self(mapper(b)?) +pub hkt Monad1(item: A) { + fn map(m: fn (from: A): B) = item is A ? Self(m(item)) : self + fn flat_map(m: fn (from: A): T) = item is A ? m(item) : self } -pub hkt Monad2 : Monad2 { - fn map_right(mapper: fn (right: B): B): T - fn flat_map_right(mapper: fn (right: B): T): T - fn fold_right(folder: fn (right: B): A): T +pub hkt Monad2(item: A | B) : Monad1(item is A ? item : Unit) { + fn map_right(m: fn (right: B): B) = item is B ? Self(m(item)) : self + fn flat_map_right(m: fn (right: B): Self) = item is B ? m(item) : self + fn fold_right(f: fn (right: B): A) = item is B ? Self(f(item)) : self } -pub hkt Reader : Monad { - impl fn map(mapper) = Self(mapper(self)) - impl fn flat_map(mapper) = mapper(self)? - fn bind(item: A): Self - fn bind_from(item_producer: fn (): A): Self - fn bind_from_map(item_mapper: fn (item: A): A): Self - fn bind_from_flat_map(item_mapper: fn (item: A): T): Self - fn ask(): A - fn use(user: fn (item: A): T): Self +pub hkt Reader2(readable: R, item: A, other: B) : Monad2(item) { + fn read(reader: fn (readable: R): A) = Self(readable, reader(readable), other) + fn use(user: fn (readable: R): Unit) = Self(readable, user(readable), other) } pub enum type Option : Monad1 { - Some(item: T) { - impl fn map(mapper) = Success(mapper(item)) - impl fn flat_map(mapper) = mapper(item)? - }, - None { - impl fn map = self - impl fn flat_map = self - } + Some(item), + None } pub enum type IO : Monad2 { - Success(item: T) { - impl fn map(mapper) = Success(mapper(item)) - impl fn flat_map(mapper) = mapper(item)? - impl fn map_right(mapper) = self - impl fn flat_map_right(mapper) = self - impl fn fold_right(folder) = self - }. - Failure(error: E) { - impl fn map(mapper) = self - impl fn flat_map(mapper) = self - impl fn map_right(mapper) = Failure(mapper(error)) - impl fn flat_map_right(mapper) = mapper(error)? - impl fn fold_right(folder) = Success(folder(error)) - } + Success(item: T), + Failure(error: E) } // usage in a file interface -decl pub fn open_file(name: String): FileReader> +pub fn open_file(name: String): FileReader { + try { + let file: LuaObject = lua {% fs.open(${name}) %} + return Success( + File { + name, + impl fn read_data() { + lua {% ${file}.readAll() %} + } + impl fn close() { + lua {% ${file}.close() %} + } + }, + Unit + ) + } catch (e: LuaError) { + return Failure(e) + } +} + +pub enum type FileReader : Reader2 { + Success(file: File, result: R) : Super(file, result, Unit), + Failure(error: E) : Super(file, Unit, error) +} pub int File { name: String - fn read_data(): IO - fn close: IO + fn read_data(): String + fn close() } -pub type FileReader : Reader> { - fld io: IO +// usage in a main file, perhaps - impl fn bind(file) { - io = Success(file) - } - - impl fn bind_from(producer) { - io = Success(producer()) - } - - impl fn bind_from_map(mapper) { - io = Success(mapper(io?)) - } - - impl fn bind_from_flat_map(flat_mapper) { - io = Success(flat_mapper(io?)?) - } - - impl fn ask() = io? - - impl fn use(user) = { - user(io?) - self +match open_file('test.txt') + .read { f -> f.read_data() } + .map { data -> data.length() } +{ + Success(file, length) => { + f.close() + println(result) + }, + Failure(error) => { + println(error.message) } } -// some other file - -open_file('test.txt') // FileReader> - .flat_map { f -> f.read_data() } // FileReader> - .use { f -> f.close() } // FileReader> - .ask()? // String -