ADT 和值
ADTs and values
在 Rascal 中,假设我有代码:
value x = 2;
data Exp = con(int n);
有没有办法调用 con(x),而 x 是一个值(但实际上是一个整数),而无需事先知道 con 的第一个参数应该是什么类型(因此没有明确地将其转换为一个整数)?
为什么可以调用一个函数,比如 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
在两种情况下都需要 return 相同的类型,并且您需要导入 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
't an int
你会得到一个你可以处理的错误,能够创建你自己的错误消息,添加额外的错误处理而不是仅仅显示一条消息,查看导致问题的值等等,而不是仅仅拥有口译员给出了一个错误(可能不会给你所有你想要的信息)。
在 Rascal 中,假设我有代码:
value x = 2;
data Exp = con(int n);
有没有办法调用 con(x),而 x 是一个值(但实际上是一个整数),而无需事先知道 con 的第一个参数应该是什么类型(因此没有明确地将其转换为一个整数)?
为什么可以调用一个函数,比如 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
在两种情况下都需要 return 相同的类型,并且您需要导入 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
't an int
你会得到一个你可以处理的错误,能够创建你自己的错误消息,添加额外的错误处理而不是仅仅显示一条消息,查看导致问题的值等等,而不是仅仅拥有口译员给出了一个错误(可能不会给你所有你想要的信息)。