[nem-en] Pattern matching using `is' loses bindings

Kamil Skalski kamil.skalski at gmail.com
Thu Jul 27 14:57:53 CEST 2006


For complex matching you should use 'match' expression - 'is' was
added just as a shortcut for simple patterns. This is especially
valid, then you want to bind some parts of pattern to variables. So
instead of

when (x is Some ((a,.b))) {
}

just do

match (x) {
  | Some ((a,b)) =>
  | _ =>
}

this is a bit longer, but it is a proper way of doing this.

In your example I would just use:

>   def x = 18 /* or 35, 8, etc */;
>   match((x, foo(x)) {
>     | (x, Some (a,b)) when x > 10 =>
>       System.Console.WriteLine($"x > 10 leads to ($a,$b)");
>     | (x, Some (a,b)) when x > 5 =>
>       System.Console.WriteLine($"x < 5 leads to ($a,$b)");
>     | (x, _) =>
>       System.Console.WriteLine($"x = $x");
>   }


On 7/27/06, Snaury <snaury at gmail.com> wrote:
> Hi everyone,
>
> I'm not sure whether it is a bug (because I think I understand why
> this happens this doesn't seem to be a bug) and needs to be fixed, but
> it's something that annoys me sometimes. Consider the code:
>
>   def foo() : option[int * int] {
>     Some((51, 67))
>   }
>
>   when(foo() is Some((a, b)))
>     System.Console.WriteLine("({0},{1})", a, b);
>
> Here I use `is' pattern matching inside of `when', because there are
> situations when it's too expensive (in terms of typing) to write full
> match. Variables a and b are reported unbound here, and I think I
> understand why: because the scope of a and b is inside of condition of
> `when', and when `when' gets result it leaves that scope, thus a and b
> just disappear. However, there are situations (in complex match cases)
> when this behaviour beats hard into my back:
>
>   def foo(i) : option[int * int] {
>     if(i > 20)
>       Some((i * 2, i * 3))
>     else
>       None()
>   }
>
>   def fee(i) : option[int * int] {
>     if(i < 10)
>       Some((i * 4, i * 2))
>     else
>       None()
>   }
>
>   match(18 /* or 35, 8, etc */) {
>     | x when (x > 10 && foo(x) is Some((a, b))) =>
>       System.Console.WriteLine($"x > 10 leads to ($a,$b)");
>     | x when (x > 5 && fee(x) is Some((a, b))) =>
>       System.Console.WriteLine($"x < 5 leads to ($a,$b)");
>     | x =>
>       System.Console.WriteLine($"x = $x");
>   }
>
> Here `when' in this (relatively simple) match is not that easy to
> refactor into another match, because we will have to match None/_ case
> and thus would never jump to the next case. I'm not sure if anything
> can be done with matching inside of when with variable bindings, but
> if only it could be improved in some way...
>
> _______________________________________________
> https://nemerle.org/mailman/listinfo/devel-en
>


-- 
Kamil Skalski
http://nazgul.omega.pl



More information about the devel-en mailing list