为什么在直接使用函数时参数中缺少显式类型声明有效,而在传递给另一个函数时则不起作用



在你的模块中定义这个函数:

module Data
int inc(x) = x + 1;

在控制台中键入以下内容:

rascal> import Data;
rascal> import List;

这有效:

rascal> inc(1);
int: 2

但这不会:

rascal> list[int] y = [1,2,3];
rascal> mapper(y, inc); 
|rascal://<path>|: insert into collection not supported on value and int
☞ Advice

但是如果声明inc(...)的参数类型,它就可以工作:

int inc(int x) = x + 1;

那么为什么没有这种类型的声明可以直接使用 inc(...) 函数,而不能将该函数传递给mapper(...)呢?

因为 Rascal 的类型检查器仍在开发中,所以如果你犯了一个小错误,比如忘记为函数参数提供类型,你不会得到警告。在某些情况下,它可能仍然会意外地工作,但正如您所观察到的那样,您肯定会在某个地方遇到麻烦。原因是函数参数的类型推断根本没有作为功能实现。这是一个语言设计决策,旨在使错误消息易于理解。

因此,这是不允许的:

int f(a) = a + 1;

并且,它应该这样写:

int f(int a) = a + 1;

我认为解释器不抱怨非类型化参数是一个错误。这是因为我们重用函数参数和内联模式的模式匹配代码。[编辑:问题已在 https://github.com/cwi-swat/rascal/issues/763 注册]

在您的情况下,该示例之所以有效,是因为动态地int值的类型,并且加法不会检查参数类型。断开的示例中断,因为解释器确实在调用站点检查函数参数的类型(对于非类型化参数,默认为 value)。

最新更新