Pattern matching with Arrays

This is really cool. I've never used F#, so thanks for pointing this out.

active-patterns Extra points for the name (| "banana clips" |).

I've had something like this on my backburner-wishlist for a while.
Customizable patterns/bindings could be very powerful.

One use case I had in mind: writing parsers for binary formats such as
msgpack <http://msgpack.org/index.html&gt;\. For instance, msgpack encodes a
uint16 as 0xcd + high byte + low byte. If the 0xcd could be given as a
parameter to the "active pattern", you could imagine writing something like

match msgpackStream { // a raw byte stream

// Scan 3 bytes, the first of which is equal to 0xcd.
// Theoretical syntax allowing a custom stream-scanner object to fill in
the two variable bindings
// by reading bytes from the stream. If the first byte were not 0xcd, the
match would fail.
case [0xcd, let hi, let lo]:
    return UInt16(hi) << 8 | UInt16(lo)
...
}

···

On Tue, Jan 3, 2017 at 10:10 AM, Joe Groff via swift-evolution < swift-evolution@swift.org> wrote:

On Dec 22, 2016, at 7:43 PM, Robert Widmann <devteam.codafi@gmail.com> > wrote:

Do you think there’s room for a more general Pattern Synonyms-like
<https://ghc.haskell.org/trac/ghc/wiki/PatternSynonyms&gt; feature that
could extend this to things that look tuple-y? We had a short conversation
on Twitter 'round about the release of Swift 1.2 about Swiftz’s HList
<https://github.com/typelift/Swiftz/blob/master/Sources/HList.swift#L185&gt; implementation
and my desire to be able to destructure them into tuples for native pattern
matching.

My personal favorite design for user-extensible pattern syntax is F#'s
"active pattern" feature, which lets you declare a set of mutual exclusive,
total or partial conditions along with a function body that computes which
condition holds. For the specific case of container patterns, though, I
feel like it's worth keeping a close association with Collection semantics,
so that:

- matches when the incoming collection's startIndex == endIndex,
- [<pattern>, <pattern-list>] fails if startIndex == endIndex, or else
matches collection[startIndex] against <pattern> and recursively matches
collection[startIndex.advancedBy(1)..<endIndex] against [<pattern-list>]
- [<pattern>...] matches the remaining collection against <pattern>

-Joe