ADT和价值观

时间:2015-07-25 15:42:15

标签: casting rascal

在Rascal,说我有代码:

value x = 2;
data Exp = con(int n);

有没有办法调用con(x),而x是一个值(但实际上是一个整数),而不事先知道con的第一个参数的类型应该是什么(因此没有明确地将它转换为int )?

为什么可以调用一个函数,比如int something(int n)= n,将一个定义为值的整数(例如值y = 2)传递给它的第一个参数,而当我输入时它给出了一个错误尝试对用户定义的ADT做同样的事情吗?

1 个答案:

答案 0 :(得分:0)

当你在Rascal中调用一个函数时,实际上它正在对参数进行模式匹配。因此,如果您定义int something(int n) = n;,然后调用something(x),则会将xint 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,那么最好只是声明它。另一种选择是创建一个像Exp makeCon(int n) = con(n);这样的函数,然后您可以根据需要使用它,即Exp myExp = makeCon(x);。在这种情况下,最好包含函数的默认版本,以防万一你给它一些意想不到的东西,比如default Exp makeCon(value x) { throw "Unexpected value <x>"; },如果你试图用一些东西创建一个con的话是int你将得到一个你可以处理的错误,能够创建自己的错误消息,添加额外的错误处理而不仅仅是显示消息,查看导致问题的值等,而不仅仅是解释器给出错误(可能无法提供您想要的所有信息)。