Rascal可能存在Bug:对嵌套列表/集合使用mapper与size函数运行时报错
问题成因
- 核心原因是多模块导入带来的函数重载歧义:你的代码同时导入了
List、Set、Map三个标准库模块,三者都定义了同名的size函数,分别对应列表、集合、映射三种容器的长度计算逻辑。 - Rascal当前的类型系统不支持对高阶函数参数做自动重载推断:当你直接把未限定命名空间的
size作为参数传递给mapper时,静态阶段无法确定该绑定哪个版本的size实现,运行时传入列表元素后匹配不到对应的函数签名,就会抛出CallFailed报错。 - 该问题和容器内存储的元素类型无关,无论是
list[list[str]]还是list[list[int]],只要没有显式消除size的重载歧义,都会触发相同报错。
是否属于预期设计
是预期行为。Rascal目前的设计要求开发者在传递重载函数作为高阶参数时,必须显式消除歧义,不会自动根据上下文的容器类型做隐式的重载绑定。
解决方案
两种写法都可以解决问题:
- 显式指定
size所属的命名空间,处理列表容器时写List::size,处理集合容器时写Set::size即可:
// 正确示例 list[int] b = mapper(a, List::size);
- 用lambda表达式包装一层,利用lambda参数的明确类型触发正确的重载解析:
list[int] b = mapper(a, (elem) => size(elem));
内容的提问来源于stack exchange,提问作者Bolderax
相关产品推荐
相关产品推荐

