List patterns

Alist patternmatches aList tfor some typetand has one of four forms:

  1. head List.+: tailmatches a list with at least one element. The patternheadis matched against the first element of the list andtailis matched against the suffix of the list with the first element removed.
  2. init List.:+ lastmatches a list with at least one element. The patterninitis matched against the prefix of the list with the last element removed, andlastis matched against the last element of the list.
  3. Aliteral list patternhas the form[p1, p2, … pn]wherep1throughpnare patterns. The patternsp1throughpnare matched against the elements of the list. This pattern only matches if the length of the scrutinee is the same as the number of elements in the pattern. The pattern[]matches the empty list.
  4. part1 List.++ part2matches a list which composed of the concatenation ofpart1andpart2.At least one ofpart1orpart2must be a pattern with a known list length, otherwise it's unclear where the list is being split. For instance,[x, y] List.++ restis okay as isstart List.++ [x, y],but justa ++ bis not allowed.

Examples:

first : [a] -> Optional a
first = cases
  h +: _ -> Some h
  []     -> None
last : [a] -> Optional a
last = cases
  _ :+ l -> Some l
  []     -> None
exactlyOne : [a] -> Boolean
exactlyOne = cases
  [_] -> true
  _   -> false
lastTwo : [a] -> Optional (a, a)
lastTwo = cases
  start ++ [a, a2] -> Some (a, a2)
  _                -> None
firstTwo : [a] -> Optional (a, a)
firstTwo = cases
  [a, a2] ++ rest -> Some (a, a2)
  _               -> None