You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As a simple extension to the current pattern matching facility, I’d like to allow match on literals, since they’re essentially the “constructors” of intrinsic types:
define fib (UInt32 -> UInt32):
-> n;
match (n)
case 0u32:
1u32
case 1u32:
1u32
else:
(n - 1u32) fib + (n - 2u32) fib
match (some_char)
case 'a':
ayy
case 'z':
zzz
else:
wat
For better usability, pattern matching needs to be extended to support more than just constructors. I have a rough idea of what it ought to look like, but haven’t worked out all the semantics.
Matching on List would be a good first step. Examples:
case []: empty list
case [...]: any list
case [_]: any list of length 1
case [_, _, _]: any list of length 3
case [a, _]: any list of length 1, binding a
case [a, ...]: any list of length 1 or greater, binding the first element
case [..., a]: any list of length 1 or greater, binding the last element
case [0, ..., 1]: any list of length 2 or greater, beginning with 0 and ending with 1
case [1, ..., ...]: error, adjacent ...
case [1, ..., 2, ..., 3]: error, patterns between ...
case [_, ...]: any list of length 1 or greater
case "abc": sugar for case ['a', 'b', 'c']
For other constructors, I think it makes sense to require parentheses and write them in postfix like constructor application. The last word in a parenthesised pattern is the constructor.
match (optional_int)
case (n some): n
case none: 0
As for lists, ... could be used to ignore multiple adjacent fields.
type Triple<A, B, C> { case triple (A, B, C) }
define third<A, B, C> (Triple<A, B, C> -> C):
match (1 2 3 triple)
case (... x triple): x
The as keyword could be reused to bind the result of a pattern match to a name, like Haskell’s @ (“as-patterns”) or OCaml’s as.
define dup_head<T> (List<T> -> List<T>):
match
case [x, ...] as xs:
x xs prepend
case []:
[]
type Rational<T>:
case rat (T, T)
define min_rational (Rational<Int32>, Rational<Int32> -> Rational<Int32>)
pair match
case ((_ 0 rat) r2 pair): r2
case (r1 (_ 0 rat) pair): r1
case (((n1 d1 rat) as r1) ((n2 d2 rat) as r2) pair):
if (n1 * d2 < n2 * d1):
r1
else:
r2
Guards could reuse the if keyword; a case could accept an if/elif/else expression as a body, and fall through to the next pattern if no condition matched. Unfortunately this is ambiguous with else as used in match, so maybe it needs to be written as case else or something.
define something_positive (Optional<Int32> -> Optional<Int32>):
-> x;
match (x)
case (n some) if (n < 0):
n neg some
else:
x
Exhaustiveness checking also becomes much more involved with more complex patterns.
The text was updated successfully, but these errors were encountered:
As a simple extension to the current pattern matching facility, I’d like to allow
match
on literals, since they’re essentially the “constructors” of intrinsic types:For better usability, pattern matching needs to be extended to support more than just constructors. I have a rough idea of what it ought to look like, but haven’t worked out all the semantics.
Matching on
List
would be a good first step. Examples:case []
: empty listcase [...]
: any listcase [_]
: any list of length 1case [_, _, _]
: any list of length 3case [a, _]
: any list of length 1, bindinga
case [a, ...]
: any list of length 1 or greater, binding the first elementcase [..., a]
: any list of length 1 or greater, binding the last elementcase [0, ..., 1]
: any list of length 2 or greater, beginning with 0 and ending with 1case [1, ..., ...]
: error, adjacent...
case [1, ..., 2, ..., 3]
: error, patterns between...
case [_, ...]
: any list of length 1 or greatercase "abc"
: sugar forcase ['a', 'b', 'c']
For other constructors, I think it makes sense to require parentheses and write them in postfix like constructor application. The last word in a parenthesised pattern is the constructor.
As for lists,
...
could be used to ignore multiple adjacent fields.The
as
keyword could be reused to bind the result of a pattern match to a name, like Haskell’s@
(“as-patterns”) or OCaml’sas
.Guards could reuse the
if
keyword; acase
could accept anif
/elif
/else
expression as a body, and fall through to the next pattern if no condition matched. Unfortunately this is ambiguous withelse
as used inmatch
, so maybe it needs to be written ascase else
or something.Exhaustiveness checking also becomes much more involved with more complex patterns.
The text was updated successfully, but these errors were encountered: