Search code examples
rascal

determine the particular kind of constructor for an ADT in rascal


The problem is as follows:

data Scalar=type1()|type2()|...

data Expr=scalar(Scalar aType)| secondForm(..) | thirdForm(..) |..

case Expr ee:binaryOperation(Expr e1,Expr e2, Op opern):
    //do something useful

How can I specify the condition to determine the type of e1 and e2, and take actions henceforth, for example,

    if(e1 != scalar(_)) //do something useful
    if(e2 != scalar(_)) //do something useful

Solution

  • You have (at least) three options.

    First, you can include that in the case:

    case Expr ee:binaryOperation(Expr e1:scalar(_), Expr e2, Op opern) :
    

    In that case, you would need a second, more general case for when e1 is not a scalar:

    case Expr ee:binaryOperation(Expr e1, Expr e2, Op opern) :
    

    This should come below the first case. I'm not a big fan of ordering dependencies, so this isn't the solution I would use.

    Second, you could match this in your conditional. This matches when it is a scalar:

    if(scalar(_) := e1)
    

    and this matches when it isn't:

    if(scalar(_) !:= e1)
    

    If you need the contents -- the value inside scalar -- you would want to put a variable in there to bind it in the match.

    Third, you could use the is operator:

    if(e1 is scalar)
    

    or

    if (!(e1 is scalar))
    

    would let you check whether e1 is, or is not, constructed using scalar. The is operator really says "the top constructor for e1 is scalar", and if that is all you need to know, that is simpler than writing a match.