Skip to content

Instantly share code, notes, and snippets.

@Nymphium
Last active September 8, 2019 21:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nymphium/3632858aa979d97a07f113ec0a7f629f to your computer and use it in GitHub Desktop.
Save Nymphium/3632858aa979d97a07f113ec0a7f629f to your computer and use it in GitHub Desktop.
public module cont
public import function
public struct ccont<r, a>(k : (a -> r) -> r)
public fun runCont<r, a>(c : ccont<r, a>): ((a -> r) -> r) {
c.k
}
public fun runCont'<r, a>(c : ccont<r, a>, f : (a) -> r) : r {
runCont(c)(f)
}
private effect econt<r, a> {
fun econt(k : ccont<r, a>): a
}
val do : forall<r, a, b>((() -> <econt<r, b>> ccont<r, a>) -> ccont<r, a>)
= handler {
econt(m) ->
Ccont(fun(k) {
m.runCont'(fun(x) {
x.resume.runCont'(k)
})
})
}
public fun cont<r, a>(f : ((r -> a) -> a)) : <econt<a, r>> r {
f . Ccont . econt
}
public fun pure<r, a>(x : a) : ccont<r, a> {
x . (|>) . Ccont
}
public fun run<r>(cont : ccont<r, r>) : r {
cont . runCont $ id
}
public fun abort<a, b>(v: a): <econt<a, b>> b {
cont(fun(_) {v})
}
public fun runAbortive<r, a>(default : r, cont : ccont<r, a>) : r {
cont . runCont $ (fun(_) { default })
}
val ok = fun() : <econt<int, int>> int {
run $ do {
val x = cont(fun(k:int -> int) { k(10) * k(10) })
val y = 20
val z = 30
return pure $ x + y + z
}
}
val abortive = fun(default : string, x : int) : string {
(fun(k) { runAbortive(default, k) }) $
do {
if (x < 9) then abort $ "ouch"
else
pure $ x
}
}
public module function
infixl 10 ($)
infixr 10 (|>)
public fun ($)<a, b>(k: a -> b): (a -> b) { return fun(x) {
k(x)
}}
public fun ($)(k, x) { k(x) }
public fun (|>)(x) { return fun(k) {
k(x)
}}
public fun (|>)(x, k) { k(x) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment