Skip to content

Instantly share code, notes, and snippets.

@pzel
Created February 26, 2019 17:12
Show Gist options
  • Save pzel/6bd91607aa4a01e2e8e77e7b33a45f75 to your computer and use it in GitHub Desktop.
Save pzel/6bd91607aa4a01e2e8e77e7b33a45f75 to your computer and use it in GitHub Desktop.
Maybe & Result implemenations of Functor Interface
class val Maybe[A: Any val] is Functor[A]
let _v : (A | None)
new val just(a: A) => _v = a
new val nothing() => _v = None
fun val fmap[B: Any val](f: {(A): B}) : Maybe[B] =>
match _v
| None => Maybe[B].nothing()
| let v' : A => Maybe[B].just(f(v'))
end
class val Result[Ok: Any val, Err: Any val] is Functor[Ok]
let _v : (Ok | Err)
new val ok(a: Ok) => _v = a
new val err(e: Err) => _v = e
fun val fmap[NewOk: Any val](f: {(Ok): NewOk}) : Result[NewOk,Err] =>
match _v
| let e' : Err =>
Result[NewOk,Err].err(e')
| let a' : Ok =>
Result[NewOk,Err].ok(f(a'))
end
interface val Functor[A: Any val]
fun val fmap[B: Any val](f: {(A): B}) : Functor[B]
class val _Dud
actor Main
new create(env: Env) =>
let inc : {(U32) : U32} = {(a:U32) => a + 10}
// We could fmap over maybes
// let maybeInt1 : Functor[U32] = Maybe[U32].just(1) // maybe.a.
// let maybeInt1 : Functor[U32] = Maybe[U32].nothing() // maybe.b.
// Or over Results
// let maybeInt1 : Functor[U32] = Result[U32, String].ok(1) // result.a.
/// ^ This doesn't work, because String happens to be the Ok type of the fmapped function, (env.out.print(a))
// let maybeInt1 : Functor[U32] = Result[U32, _Dud].ok(1) // result.a.
// ^ This works, because the Ok pattern doesn't match the lambda's type
// let maybeInt1 : Functor[U32] = Result[U32, String].err("bad stuff") // result.a.
maybeInt1.fmap[U32](inc)
.fmap[U32](inc)
.fmap[String]({(a: U32) => a.string()})
.fmap[None]({(a: String) => env.out.print(a)})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment