Looking at the docs it only seems like rescript has the ability to iterate over ranges, is there any way to define custom iterators? Or just iterate over the contents of an array?
I’m not sure what you are trying to do exactly.
For arrays, there are:
Belt.Array.map: you provide an array and a “map function”, you get a new array containing the “mapped” elements (result of the map function applied to every element of the input array
Belt.Array.forEach: similar to above, the “map function” needs to return
unit(aka is doing some side effects), it finally returns
There are also other functions with similar names in
Belt.Array having slightly different types.
let x = ["hello", "hi", "hola"] // Note: y is a new array, x won't be modified let y = x->Belt.Array.map(el => el ++ " world") y->Belt.Array.forEach(el => Js.log(el))
It might be that I’m just too used to thinking in terms of other languages that have either traits or some form of polymorphism which I’m guessing rescript doesn’t have?
Like if I’m designing a custom container and I wanted it to implement foreach I just write a forEach implementation for it in rescript? I can’t go and pass that to a function that takes any iterator though right?
Rescript has polymorphism, but it seems not in a way you are used to…
- function overloading is not supported: a function (“name”) has exactly one type signature.
- most commonly are type parameters used, like
array<'a>, when you don’t care about the actual “container’s content”
- edit: there are other ways as well, which I’m not going into here
It depends on how you define an iterator in the language you are working in…
If you are familiar with “type classes” or “category theory”: Rescript has
functors. Which are “higher order functions” taking one or several modules as arguments and returning a new module. Heavy functor usage doesn’t translate well to compiled js, therefore it’s discouraged
But there are still applications for it.
In your example, you could define a
module type specifying functions needed any module needs to provide to be iterable. A functor could then be implemented which takes any module according to this type and returns functions like
The reason why most of the builtin types have their own functions is, that they are essentially bindings to their js counterparts. Therefore a common iterable interface is unnecessary there.
See Implementing the iterable protocol (Symbol.iterator) - #5 by kevinbarabash for previous discussion about iterators.
AsyncIterator.make for creating JS iterators, hiding the creation behind a type safe interface. Feel free to open an issue on the repo if that’s of interest.