lib: add some list utilities
Adds `unfold` for constructing a list from a generating function, and adds `range` for constructing a range of numbers. Signed-off-by: Edward Pierzchalski <ed.pierzchalski@data61.csiro.au>
This commit is contained in:
parent
b7525f8d43
commit
b153cb9571
|
@ -28,6 +28,29 @@ sig
|
|||
found element.
|
||||
*)
|
||||
val find_index: ('a -> bool) -> 'a list -> int option;
|
||||
|
||||
(*
|
||||
`unfold f init` repeatedly calls `f` to construct elements
|
||||
of a list, until it returns NONE. For example:
|
||||
|
||||
`unfold
|
||||
(fn idx => if idx < 10 then SOME ("hello", idx + 1) else NONE)
|
||||
7
|
||||
= ["hello", "hello", "hello"]`
|
||||
|
||||
`unfold (fn x => SOME (1, x)) anything` never returns.
|
||||
|
||||
`unfold (K NONE) anything = []`
|
||||
*)
|
||||
val unfold: ('acc -> ('item * 'acc) option) -> 'acc -> 'item list;
|
||||
|
||||
(* `range from to` produces the list of integers between
|
||||
`from` (inclusive) and `to` (exclusive). For example:
|
||||
|
||||
`range 3 5 = [3, 4]`
|
||||
`range ~1 2 = [~1, 0, 1]`
|
||||
*)
|
||||
val range: int -> int -> int list;
|
||||
end
|
||||
|
||||
structure ListExtras: LIST_EXTRAS =
|
||||
|
@ -44,4 +67,12 @@ fun map_find_first (f: 'a -> 'b option) (xs: 'a list): 'b option =
|
|||
fun find_index test =
|
||||
Library.get_index (fn x => if test x then SOME () else NONE) #> Option.map fst
|
||||
|
||||
fun unfold (f: 'acc -> ('item * 'acc) option) (acc: 'acc) =
|
||||
case f acc of
|
||||
NONE => []
|
||||
| SOME (item, new_acc) => item :: unfold f new_acc;
|
||||
|
||||
fun range from to =
|
||||
unfold (fn i => if i < to then SOME (i, i + 1) else NONE) from;
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue