[英]ADTs and values
在Rascal中,说我有代码:
value x = 2;
data Exp = con(int n);
有一种方法可以调用con(x),而x是一个值(但实际上是一个整数),而无需事先知道con的第一个参数的类型应该是什么(因此无需将其显式转换为int)?
为什么可以调用一个函数,比如说int something(int n)= n,并将定义为一个值(例如,值y = 2)的整数传递给它的第一个参数,而当我尝试执行此操作时却给我一个错误用户定义的ADT是否相同?
当您在Rascal中调用函数时,它实际上是对参数进行模式匹配。 因此,如果您定义int something(int n) = n;
,然后调用something(x)
,它将x
与int n
匹配,看到x
实际上是一个int
(因此可以将值绑定到n
),然后调用该函数。
如果要改为定义value x = 2.5
,然后再调用something(x)
,则会收到错误消息,因为它无法将值2.5
绑定到int n
。 您可以使用第二个定义来重载something
,而该定义需要一个实数,例如int something(real r) = toInt(r);
,然后它将起作用。 不过,这里需要注意两点:在两种情况下, something
需要返回相同的类型,并且您需要导入util::Math
才能访问toInt
。
当您使用诸如con(x)
类的构造函数时,它不会自动为您进行模式匹配。 您提供的类型必须与期望的类型匹配。 如果您知道x
始终是int
,则最好将其声明为int
。 另一种选择是创建一个像Exp makeCon(int n) = con(n);
的函数Exp makeCon(int n) = con(n);
然后您可以Exp myExp = makeCon(x);
使用它,即Exp myExp = makeCon(x);
。 在这种情况下,最好包含该函数的默认版本,以防万一您给它带来了意外的情况,例如default Exp makeCon(value x) { throw "Unexpected value <x>"; }
default Exp makeCon(value x) { throw "Unexpected value <x>"; }
,这样,如果您尝试使用非int
东西创建con
,您将得到可以处理的错误,并且能够创建自己的错误消息,添加其他错误处理功能,而不仅仅是显示一条消息,查看导致问题的值等,而不只是让解释器给出错误(这可能无法为您提供所需的所有信息)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.