⛅ Coming soon: create Unison Cloud clusters in minutes on your own infrastructure. Learn more

Destructuring binds

Tuples and data types can be decomposed with pattern matching, but Unison also provides several ways to more concisely bind variable names to the corresponding parts of a data structure.

Destructuring tuples

Variables can be assigned to the constituent parts of a tuple by surrounding the variable definition with parentheses and separating the variables with commas.

use Nat + tuple = (1, 2) let (first, second) = tuple first + second
3

🎨 If a tuple is passed as an argument to a lambda, you can use the cases keyword as a way to destructure the tuple.

jsonschema.lib.base.data.List.map (cases (first, second) -> second) [(1, 2), (3, 4)]

Destructuring data types

The fields of a data type can also be bound to variables by destructuring their data constructors

Say you have a simple Box type:

You could write a function that adds two Box Nat types together by accessing the Nat elements like this:

addBox : Box Nat -> Box Nat -> Nat
addBox boxA boxB =
  use Nat +
  (Box a) = boxA
  (Box b) = boxB
  a + b

So destructuring a data type takes the form (DataConstructor field1 field2 … fieldN) = instanceOfDataType

Usage notes

Currently, Unison does not support decomposition in term definitions, so a function which accepts a tuple or data type as a parameter cannot be destructured when the function parameter is first named. This means a termDeclaration like addTwo : (Nat, Nat) -> Nat can not be implemented with a term definition which starts with addTwo (one,two) = one + two. The decomposition of the tuple would have to be done on a separate line.

In some languages you can use list constructors like List.+: or List.:+ to name separate elements in the list. We do not currently support that feature for term definitions, but you can use them in pattern matching; see list pattern matching for more details.

-- you can't do this
list = [1,2,3,4]
one +: tail = list
list = [1, 2, 3, 4]

(one +: tail) = list