Utilities for ReScript. Includes:
- Sequences are now in a separate repository.
- A lazy-promise
Task
andTaskResult
- Untagged
Union
andLiteral
to construct and pattern match on discriminated unions of any kind - Useful extensions to
Option
,Result
, andArray
NonEmptyArray
for arrays with at least 1 item- A simple
Test
runner - Comparison utilities
Trampoline
module to remove recursion
npm install @jmagaram/rescript-extras
Add to your rescript.json
...
{
...
+ "bs-dependencies": ["@jmagaram/rescript-extras"]
}
Everything is accessible in the root-level Extras
module.
let arr = "abc" -> Extras.NonEmptyArray.of1
let opt = Some(1) -> Extras.Option.isSomeAnd(i => i >= 1)
Inspired by TaskEither in fp-ts, a Task
is a lazy promise that never fails. The Task.Result
works with lazy promises that always return an Error
or an Ok
. Just like a regular result
, you can transform it before execution with map
, mapError
, flatMap
, and toOption
. When ready to execute, call toPromise
.
The Union
module provides functors to create tagged and untagged discriminated unions of 2, 3, 4, or 5 items. This is useful for interop with JavaScript libraries that produce or expect simple types like string | number
and more complex types where the choices are tagged differently than how ReScript does it. See usage examples. Capabilities:
- Discriminate (pattern match) on any programmable criteria, like
typeof
,instance of
, lightweight shape detection (such as a tag), or parsing with a JSON parsing library. - All types can participate in a union.
- Custom equality
- Literal values like
Null
,Undefined
,True
,False
,-1
, and custom literals viaMakeString
,MakeInt
, etc. - Built-in support for
Int
,String
,Bool
,Float
,option<t>
,nullable<t>
,null<t>
, and tuples of length 2 and 3
This implementation does not utilize any special compiler support and so there are some limitations:
- Pattern matching must rely on a
match
function, not the usual matching syntax. Each case is distinguished byA
|B
|C
|D
. This can be easily improved by extending or wrapping the produced module; see the test file for examples. - Literal support and functors are a bit cumbersome
- No genType support
- No recursive type definition
Note: It is possible to create untagged unions with a library like rescript-struct and not use the functors defined in this package. See the usage examples for a comparision of the two approaches. This works very well and avoids abstractions, but requires a bit more code.
Note: The Rescript compiler has a new feature for untagged unions that works great with pattern matching support. There are limitations on which types can be included in the union, literal support is very nice, pattern matching is not customizable, and custom equality is not provided.
Functors to create Literal
types of various kinds using MakeString
and MakeInt
and others. Includes built-in literals for True
, False
, and Null
. You can create literals from reference types, and provide a custom equality operator to do things like case-insensitive string comparison. This implementation is completely type safe because each literal is its own unique type; you can't just cast any string to a "yes" for example.
Existential quanitifiers isSomeAnd
and isNoneOr
. Create an option from a function that may fail using fromTryCatch
. Combine options with concat
, map2
, map3
, and map4
. "Add" an option to a regular value using fold
and foldBack
. Includes lazy forms such as orElseWith
.
An array that must have at least one item in it. Include many of the usual functions like reduce
, maxBy
, minBy
, map
, mapi
, concat
, head
, etc. Convert toArray
and fromArray
.
Generate an array from a generator function using unfold
. Various utilities like head
, last
, lastIndex
, isEmpty
, and prepend
.
Convert an array of results to a single result using fromArray
and fromArrayMap
. Create a result from a function that may fail with fromTryCatch
. Transform an error with mapError
.
Similar to the Types
module, includes functions to safely inspect unknown values like toString
and toInt
that returns an option. Can inspect properties on objects as well. Not intended for full-featured JSON parsing.
Cmp.t
is the ('a,'a) => float
comparison function. The Cmp
module provides comparison utilities such as as eq
, neq
, lt
, gte
, min
, and max
. fromMap
makes it easy to generate a comparison function for an object based on a specific property in it. Or use reverse
to change direction.
Functors MakeCompare
and MakeEquals
add sorting and equality functions to your custom data types.
Simple tools to remove recursion and avoid stack overflows.
Super-simple test runner. Make tests using make
and makeAsync
. Run them using runSuite
.