Skip to content

Instantly share code, notes, and snippets.

@schicks
Created January 2, 2021 18:55
Show Gist options
  • Save schicks/5542f949e7af63ca66e5c167e8d1e294 to your computer and use it in GitHub Desktop.
Save schicks/5542f949e7af63ca66e5c167e8d1e294 to your computer and use it in GitHub Desktop.
Koka for loops
effect leq<a> {
fun leq(first: a, second: a) : bool
}
fun for(
from: a,
incr: a -> <div,leq<a>|e> a,
to: a,
do: () -> <div,leq<a>|e> ()
) : <div,leq<a>|e> () {
if (from.leq(to)) then {
do();
for(from.incr, incr, to, do)
} else ()
}
fun using-for () {
var something := 0
with fun leq(first: int, second: int) {first <= something}
for(0, fn (a) {a+1}, 10) {
something := something + 1
}
var something-else := "a"
with fun leq(first: string, second: string) {first <= second}
for("", fn (a) {a+"a"}, "aaaaaaa") {
something-else := something-else + "a"
}
(something, something-else)
}
@TimWhiting
Copy link

Effects with type parameters are no different than generic parameters as being stack generic or whatever the term might be. One major difference with implicits is that the compiler automatically applies as much as it can at the place most close to the function that needs it. So if you want to show a list<(a,a)> you don't need to "drill" down the implementation of show for lists or tuples, just for the generic type a. Also, at the place you call the function, if a is instantiated to something non-generic the compiler automatically supplies the correct show function as long as it is unambiguous. In other words, you trade adding a generic effect on the return type for adding a generic function in the parameter list, and you don't have to provide a handler in the dynamic scope. You also get more clear lexically scoped passing of the implementation, instead of an implicit dynamically scoped implementation, which could unexpectedly be overridden by a user function passed in.

@schicks
Copy link
Author

schicks commented Jan 18, 2024

But don't you need a generic function parameter for each "type class" you're handling? Or is there a way that your one generic function argument can be row typed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment