deimos-lang/sketching/hkt.dm
2024-11-26 09:38:49 -06:00

72 lines
1.6 KiB
Plaintext

pub hkt Monad[T<A>] {
fn <B> map(m: fn (from: A) => B): T<B>
fn <B> flat_map(m: fn (from: A) => T<B>): T<B>
}
pub hkt Monad[T<A, B>] : Monad[T<B>] {
fn map_left(m: fn (left: A) => B): T<B>
fn flat_map_left(m: fn (left: A) => T<B>): T<B>
}
pub enum Option<T> : Monad {
Some(item) {
impl fn map(m) = Some(m(item))
impl fn flat_map(m) = m(item)
},
None {
impl fn map(m) = self
impl fn flat_map(m) = self
}
}
pub enum Either<E, A> : Monad {
Left(e: E) {
impl fn map(m) = self
impl fn flat_map(m) = self
impl fn map_left(m) = Right(m(e))
impl fn flat_map_left(m) = m(e)
},
Right(a: A) {
impl fn map(m) = Right(m(a))
impl fn flat_map(m) = m(a)
impl fn map_left(m) = self
impl fn flat_map_left(m) = self
}
}
// Usage of Either in a file interface.
pub int File {
name: String
fn read_data(): String
fn close()
}
#target[lua]
impl LuaFile(name: String, fld file: LuaObject) : File {
impl fn read_data() = lua {% $file.readAll() %}
impl fn close() = lua {% $file.close() %}
}
#target[lua]
pub fn open_file(name: String): Either<Error, File> {
try {
Right(LuaFile(name, lua {% fs.open($name) %}))
} catch (e: LuaError) {
Left(e)
}
}
// Usage in a main file, perhaps.
// Note this part would be platform independent.
let data_length = match open_file('test.txt') {
Left(error) => println(error.message),
Right(file) => {
let data_length = f.read_data().length()
f.close()
data_length
}
}
println(data_length)