Implement List.find

`List.find : List elem, (elem -> Bool) -> Result elem [ NotFound ]*`
behaves as follows:

```
>>> List.find [1, 2, 3] (\n -> n > 2)
Ok 2
>>> List.find [1, 2, 3] (\n -> n > 4)
Err NotFound
```

We implement this as builtin in two phases. First, we call out to a
pure-llvm-lowlevel `ListFindUnsafe` that returns a record indicating
whether a satisfying element was found, and the value of that element
(the value is all null bytes if the element wasn't found). Then, we lift
that record to a `Result` via a standard construction of the can AST.

Closes #1909
This commit is contained in:
ayazhafiz 2021-11-07 20:56:46 -05:00
parent 35df58c18f
commit f65b174ab5
16 changed files with 417 additions and 8 deletions

View file

@ -47,6 +47,7 @@ pub enum LowLevel {
ListDropAt,
ListSwap,
ListAny,
ListFindUnsafe,
DictSize,
DictEmpty,
DictInsert,
@ -225,6 +226,7 @@ macro_rules! higher_order {
| ListKeepErrs
| ListSortWith
| ListAny
| ListFindUnsafe
| DictWalk
};
}
@ -259,6 +261,7 @@ impl LowLevel {
ListKeepErrs => 1,
ListSortWith => 1,
ListAny => 1,
ListFindUnsafe => 1,
DictWalk => 2,
}
}

View file

@ -1066,6 +1066,8 @@ define_builtins! {
43 LIST_JOIN_MAP_CONCAT: "#joinMapConcat"
44 LIST_ANY: "any"
45 LIST_TAKE_FIRST: "takeFirst"
46 LIST_FIND: "find"
47 LIST_FIND_RESULT: "#find_result" // symbol used in the definition of List.find
}
5 RESULT: "Result" => {
0 RESULT_RESULT: "Result" imported // the Result.Result type alias