Skip to content

Instantly share code, notes, and snippets.

@gaku-sei
Created September 2, 2019 01:58
Show Gist options
  • Save gaku-sei/c304134b0a008c038167a4769bf8e3cc to your computer and use it in GitHub Desktop.
Save gaku-sei/c304134b0a008c038167a4769bf8e3cc to your computer and use it in GitHub Desktop.
Nonempty lists with clean syntax in Reason (requires Bucklescript 6.*)
type empty;
type nonempty;
type t(_, _) =
| []: t('a, empty)
| ::('a, t('a, _)): t('a, nonempty);
let rec fromList: ('a, list('a)) => t('a, nonempty) =
x =>
fun
| [] => [x]
| [head, ...rest] => [x, ...fromList(head, rest)];
let rec toList: type a. ('b, t('b, a)) => list('b) =
x =>
fun
| [] => []
| [x] => [x]
| [head, ...rest] => [x, ...toList(head, rest)];
let rec map: type a. (t('b, a), 'b => 'c) => t('c, a) =
fun
| [] => (_ => [])
| [head, ...tail] => (f => [f(head), ...map(tail, f)]);
let head: t('a, nonempty) => 'a =
fun
| [head, ..._] => head;
[1]->head->Js.log; // Compiles and works as expected, notice that an int is returned, not an option(int)
// []->head->Js.log; // Doesn't even compile!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment