[nem-en] Pattern matching using `is' loses bindings
Kamil Skalski
kamil.skalski at gmail.com
Thu Jul 27 18:55:17 CEST 2006
Well in general I just use the another nested match expression in such cases
| _ =>
match (Util.QidOfExpr(expr)) {
| Some((id, name))) =>
def ctx = name.GetEnv(env)
if(ctx.LookupType(id) is Some(_))
true
| _ => false
}
but indeed it can be wrong, as sometimes it would require you to
repeat some cases in inner and outer match. I would like to see if
this can be somehow solved.
If you really like to make your code pretty, you can use the matching
over properties:
>>>>>>>>>>>>>>>
[Record]
class A {
x : int;
public Prop : option [int * string]
{
get {
if (x > 0)
Some ((x, "aa"))
else
None ()
}
}
}
def f (x : A) {
| (Prop = Some ((x,"aa"))) =>
System.Console.WriteLine (x);
| (Prop = None) =>
System.Console.WriteLine (0);
| _ => ()
}
f(A(11));
f(A(-1));
>>>>>>>>>>>>>>>>>>>>>>>>
In the examples you gave it would be possible to create a "matching
wrapper", which could hold the complex logic of checking multiple
aspects of data. If given case is correct, it would return the final
object with data you could bind to.
On 7/27/06, Snaury <snaury at gmail.com> wrote:
> On 7/27/06, Kamil Skalski <kamil.skalski at gmail.com> wrote:
> > 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");
> > > }
>
> Actually, I had different calls there: for one case it was foo() and
> for the other it was fee(). And that wasn't really a real world
> example, it was just to show difficulties. Doing (x, foo(x)) won't
> help, because sometimes, depending on argument it might need to call
> different functions (foo(x) in that case are functions to
> check-and-transform x, and I imagined to use match to route different
> x to different transform functions, which might fail and then try next
> one), and in some cases it might even be meaningless to call any
> foo(), plus different foo() might return different results. Anyway,
> not like I have any really unavoidable problems with this (I can
> refactor but sometimes it just looks ugly). It was more of a
> theoretical problem...
>
> I'm not sure when I first encountered this, but only recently it did
> hit me again, when I was writing special() for late macro. Because at
> first I wanted to write it like this:
>
> public special(expr : PExpr) : bool
> | PExpr.This => true
> | PExpr.Base => true
> | _ when(Util.QidOfExpr(expr) is Some((id, name))) =>
> def ctx = name.GetEnv(env)
> if(ctx.LookupType(id) is Some(_))
> true
> else if(ctx.LookupMacro(id) is Some(_))
> true
> | _ => false
>
> This way it was just looking better and I felt it to be more editable
> in future, but then I found it doesn't work and remembered I can't use
> variable bindings in when. I understand why this doesn't work and why
> it might be (almost) impossible to do it the way I dream, but still...
> It's just "wouldn't it be good if" thing then...
>
> _______________________________________________
> https://nemerle.org/mailman/listinfo/devel-en
>
--
Kamil Skalski
http://nazgul.omega.pl
More information about the devel-en
mailing list