Skip to content

Instantly share code, notes, and snippets.

@thedeemon
Created June 21, 2025 21:44
Show Gist options
  • Save thedeemon/8315a6677f64f5203a869669a997b7eb to your computer and use it in GitHub Desktop.
Save thedeemon/8315a6677f64f5203a869669a997b7eb to your computer and use it in GitHub Desktop.
class Iterator it -> a {
next : it -> Maybe a
}
type IotaIter {
mut cur : Int
end : Int
}
instance Iterator IotaIter Int {
next it =
if it.cur < it.end then do
x = it.cur
it.cur := x + 1
Some x
else None
}
iota n = IotaIter 0 n
type ArrayIter e {
arr : Array e
mut pos : Int
}
instance Iterator (ArrayIter e) e {
next it =
if it.pos < length it.arr then do
x = it.arr[it.pos]
it.pos := it.pos + 1
Some x
else None
}
class Sequence s -> e it where Iterator it e {
getIterator : s -> it
}
instance Sequence (Array t) t (ArrayIter t) {
getIterator arr = ArrayIter arr 0
}
instance Sequence t e t where Iterator t e {
getIterator it = it
}
type Filter iter e {
orig : iter
pred : e -> Bool
}
instance Iterator (Filter r e) e where Iterator r e {
next f =
match (next f.orig) {
| None => None
| (Some x) => if f.pred x then Some x else next f
}
}
filter : (elt -> Bool) -> seq -> Filter it elt where Sequence seq elt it
filter p seq = Filter (getIterator seq) p
type MapResult iter a b {
orig : iter
func : a -> b
}
instance Iterator (MapResult r a b) b where Iterator r a {
next m =
match (next m.orig) {
| None => None
| (Some x) => Some (m.func x)
}
}
map : (a -> b) -> seq -> MapResult it a b where Sequence seq a it
map f seq = MapResult (getIterator seq) f
instance HasLength (MapResult r a b) where HasLength r {
length m = length m.orig
}
instance HasLength (ArrayIter e) {
length it = length it.arr
}
instance HasLength IotaIter {
length it = it.end - it.cur
}
instance OpIndex (MapResult r a b) b where OpIndex r a {
opIndex m i = m.func m.orig[i]
}
instance OpIndex (ArrayIter e) e {
opIndex it i = it.arr[it.pos + i]
}
println x = do
puts (show x)
puts "\n"
printIt it =
match (next it) {
| (Some x) => do println x
printIt it
| None => ()
}
m = iota 5 ^ filter {x => x < 3 } ^ map { x => x }
printIt m
iota 5 ^ filter {x => x < 3 } ^ map { x => "aaa " ~ show x } ^ printIt
[1,5,2] ^ filter {x => x < 3 } ^ map { x => "bbb " ~ show x } ^ printIt
[1,5,2] ^ map { x => "ccc " ~ show x } ^ printIt
iota 5 ^ map { x => x + 500 } ^ length ^ println
mapres = [20,30,40] ^ map show
length mapres ^ println
println mapres[1]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment