Description
I think it'd be great to have some extensible way for users to write their own patterns. The following is a strawman based on haskell's view patterns. (expr -> pat)
is a pattern that evaluates the expression expr
(which should be a function), calls it on the value we are matching, and matches the output against the pattern pat
.
-> x + 1
(oneMore -> x) = 3 # sets x = 4
(oneMore -> 4) = 3 # arbitrary patterns allowed after the ->
((oneMore..oneMore) -> x) = 3 # arbitrary exprs allowed before the ->
(oneMore -> 6) = 3 # match error
# not sure which situations can get away without parentheses if any.
# parentheses are definitely needed in arrow functions to disambiguate from curried lambdas
[1, 2, 3] |> fmap$((oneMore -> x) -> x * x) # produces [4, 9, 16]
The user function should be able to raise MatchError
to reject matching against the input.
One use case for this is for validating arguments at runtime (for properties too difficult to express with type annotations), or for writing custom conditions in which a certain overload of an @addpattern
function should be used.
And of course, there's also the obvious reasons: Who wouldn't like to pattern match a fractions.Fraction
as (numer, denom)
?
fracpat = f -> (f.numerator, f.denominator)
def approx(fracpat -> (numer, denom)) = numer / denom