Can you unpack values in pony pattern matching?

159 Views Asked by At

Pony has the ability to pattern match on classes and also assign results in match expressions (with let ... :), but is there a way to unpack values in match expressions? For example something like this?

actor Main
  fun f(x: (Foo | Bar)): String =>
    match x
    | Foo(1) => "one"
    | Foo(2) => "two"
    | Foo(x) => x.string() // fails
    else
      "Bar"
    end

The only alternative I can think of is a series of

actor Main
  fun f(x: (Foo | Bar)): String =>
    match x
    | Foo(1) => "one"
    | Foo(2) => "two"
    | Bar => "Bar"
    else
      try
        let f = x as Foo
        f.number.string()
      end
    end

But that doesn't read as well, especially if there are multiple possible classes to match on.

1

There are 1 best solutions below

0
On BEST ANSWER

I assume you have accompanying definitions like this:

class Foo is (Equatable[Foo box] & Stringable)
  var value: I32 = 1
  new create(value': I32) => value = value'
  fun box eq(other: Foo box): Bool => value == other.value
  fun string(): String iso^ => value.string()

primitive Bar

Then you can bind names for whole values of a certain type, like this:

actor Main
  fun f(x: (Foo | Bar)): String =>
    match x
    | Foo(1) => "one"
    | Foo(2) => "two"
    | let x': Foo => x'.string()
    else
      "Bar"
    end

I think this is not too bad in this particular case, but it's certainly not a true destructuring bind. Pony supports such patterns only for tuples, of the form (let first: First, let second: Second).