72 lines
1.6 KiB
Plaintext
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)
|