Syntax for unwrapping Option inside function

I find ReScript to be quite interesting language, however AFAIK it doesn’t support any dedicated syntax for unwrapping Option type. We have to compare Option in the switch statement, or do some kind of flatMap/forEach/whatnot chain. ReScript even doesn’t offer destructing in if statement (like Rust’s if let Some(variable) = variable). Other languages implement such QoL syntax that way or another, so I think it’s pretty common issue:

[here goes Haskell “do” notation, but I’m new user, and cannot post more than two links]

All of these 3 mentioned have one thing in common: they change function signature to be of the same type. In Rust ? used on Option requires containing function to return an Option for example. In some sense it is the same function colouring that happens with async/await syntax in JS.

Such syntax would be incredibly helpful, I hope most of you can agree.

Did I miss something (there is such syntax or a good enough workaround [not just >any< workaround]), or maybe there was some discussion ongoing on that?

There has been both discussions about automatic optional chaining and if let and it’s something we want in some form, but still not sure how.

2 Likes

Pattern matching is possible today.

type t =
  | A(int)
  | B(int)

...
let A(x) | B(x) = A(1)

The problem is that there is no way to handle unmatched patterns without early return semantics.

For example in Rust, ? is an abbreviation for this:

let Ok(a) = result else {
  return result.into()
}

Is there any docs about this syntax? Never seen it before and curious where it’s useful

It is inherited from OCaml like any other grammars. I can’t find the documentation, basically destructuring in ReScript/Rust is another form of the pattern matching.

It is useful when dealing with variants that share the same data structure.

type event
  | Created({ date: Date.t, name: string, email: string })
  | Deactivited({ date: Date.t, by: option<adminId> })

// As long as you can
switch event {
| Created({ date }) | Deactivated({ date }) =>
  // `date` binding available here
}

// you can also this in the same place
let Created({ date }) | Deactivate({ date }) = event

However, unlike the switch, let patterns in ReScript/OCaml don’t handle patterns with different structures.

Rust expand this with the let-else binding

This is very useful when combined with early return. It can eliminate multiple nested switchs for destructuring.

https://rust-lang.github.io/rfcs/3137-let-else.html

The ? for Result is simply syntax sugar for pattern matching and early return through Rust’s trait specialization.

2 Likes