将列表附加到列表列表时,Rascal 会删除类型信息
Rascal erases type information when appending a list to a list of lists
我有以下功能:
public list[list[loc]] populateBeforeRemoval(){
list[list[loc]] dupList = [];
map[int, list[loc]] finalizedDups = ();
// Here some stuff is added to the finalizedDups map, however, I have omitted it for simplicity.
for(dup <- finalizedDups){
dupList+=finalizedDups[dup];
}
return dupList;
}
然而,当我运行这个函数时,我得到以下输出:
|project://TestProject/src/astCreation.rsc|(4955,3,<142,40>,<142,43>): Expected list[list[loc]], but got list[value]
Advice: |http://tutor.rascal-mpl.org/Errors/Static/UnexpectedType/UnexpectedType.html|
当我点击消息时,它指向代码中的 return 值 (dupList
)。似乎添加 finalizedDups[dup]
删除了列表的类型(list[loc]
)。这应该不可能吧?
为了完整起见,这里是整个(实际)函数:
public list[list[loc]] populateBeforeRemoval(list[list[loc]] dupList, list[loc] potentialDuplicates, list[loc] newPotentialDuplicates, loc location, int lineNumber){
map[int, list[loc]] finalizedDups = ();
for(dup <- potentialDuplicates, getSourceLength(dup)>=6){
bool sameIn = false;
for(pot <- newPotentialDuplicates){
if(pot.uri == dup.uri && pot.begin.line == dup.begin.line){
sameIn = true;
}
}
if(!sameIn){
int srcLength = getSourceLength(dup);
if(srcLength in finalizedDups){
finalizedDups[srcLength]+=dup;
} else {
location.end.line = lineNumber-1;
location.begin.line = lineNumber-srcLength-1;
finalizedDups[srcLength]=[location, dup];
}
}
}
for(dup <- finalizedDups){
dupList+=finalizedDups[dup];
}
return dupList;
}
更新:
一开始这段代码在 eclipse 中显示了很多错误 IDE。将 dup
重命名为其他名称后,大多数这些错误都消失了。这可能是因为 dup
是我导入的 List.rsc
(http://tutor.rascal-mpl.org/Rascal/Libraries/Prelude/List/dup/dup.html) 中的一个函数。似乎是 Eclipse 插件的问题,显示为错误的行不会在 运行 时间内产生错误。
然而主要问题并没有解决。我认为这个问题是由于将列表附加到列表列表。
不错的代码。让我们来看看。只是从阅读 not 运行 我怀疑 += 运算符将元素类型扩展到 'value'.
要知道的事情:
- "+="(仍然)对列表中的连接和元素添加超载
- 如果两种语义混淆,则赋值的新元素类型是整个列表类型与其元素类型之间的最小上限,通常为 'value'
- 它有助于用列表括号将有问题的赋值的右侧包裹起来,以强制使用“+=”的串联语义
未经请求的旁注:理解和关系运算符通常更快:
for(dup <- finalizedDups){
dupList+=finalizedDups[dup];
}
可能是:
dupList += [*finalizedDups[dup] | dup <- finalizedDups)];
然后 += 是一个单一的连接,生成器像以前一样遍历键,* 将映射中的每个列表值拼接到结果列表中。我没有测试这个只是大声思考。它更快,因为在引擎盖下 Rascal 可以使用瞬态可变状态直到列表理解完成,而 for 循环替代方案不假设任何内容并且仅使用不可变内部 API。
我有以下功能:
public list[list[loc]] populateBeforeRemoval(){
list[list[loc]] dupList = [];
map[int, list[loc]] finalizedDups = ();
// Here some stuff is added to the finalizedDups map, however, I have omitted it for simplicity.
for(dup <- finalizedDups){
dupList+=finalizedDups[dup];
}
return dupList;
}
然而,当我运行这个函数时,我得到以下输出:
|project://TestProject/src/astCreation.rsc|(4955,3,<142,40>,<142,43>): Expected list[list[loc]], but got list[value]
Advice: |http://tutor.rascal-mpl.org/Errors/Static/UnexpectedType/UnexpectedType.html|
当我点击消息时,它指向代码中的 return 值 (dupList
)。似乎添加 finalizedDups[dup]
删除了列表的类型(list[loc]
)。这应该不可能吧?
为了完整起见,这里是整个(实际)函数:
public list[list[loc]] populateBeforeRemoval(list[list[loc]] dupList, list[loc] potentialDuplicates, list[loc] newPotentialDuplicates, loc location, int lineNumber){
map[int, list[loc]] finalizedDups = ();
for(dup <- potentialDuplicates, getSourceLength(dup)>=6){
bool sameIn = false;
for(pot <- newPotentialDuplicates){
if(pot.uri == dup.uri && pot.begin.line == dup.begin.line){
sameIn = true;
}
}
if(!sameIn){
int srcLength = getSourceLength(dup);
if(srcLength in finalizedDups){
finalizedDups[srcLength]+=dup;
} else {
location.end.line = lineNumber-1;
location.begin.line = lineNumber-srcLength-1;
finalizedDups[srcLength]=[location, dup];
}
}
}
for(dup <- finalizedDups){
dupList+=finalizedDups[dup];
}
return dupList;
}
更新:
一开始这段代码在 eclipse 中显示了很多错误 IDE。将 dup
重命名为其他名称后,大多数这些错误都消失了。这可能是因为 dup
是我导入的 List.rsc
(http://tutor.rascal-mpl.org/Rascal/Libraries/Prelude/List/dup/dup.html) 中的一个函数。似乎是 Eclipse 插件的问题,显示为错误的行不会在 运行 时间内产生错误。
然而主要问题并没有解决。我认为这个问题是由于将列表附加到列表列表。
不错的代码。让我们来看看。只是从阅读 not 运行 我怀疑 += 运算符将元素类型扩展到 'value'.
要知道的事情:
- "+="(仍然)对列表中的连接和元素添加超载
- 如果两种语义混淆,则赋值的新元素类型是整个列表类型与其元素类型之间的最小上限,通常为 'value'
- 它有助于用列表括号将有问题的赋值的右侧包裹起来,以强制使用“+=”的串联语义
未经请求的旁注:理解和关系运算符通常更快:
for(dup <- finalizedDups){
dupList+=finalizedDups[dup];
}
可能是: dupList += [*finalizedDups[dup] | dup <- finalizedDups)];
然后 += 是一个单一的连接,生成器像以前一样遍历键,* 将映射中的每个列表值拼接到结果列表中。我没有测试这个只是大声思考。它更快,因为在引擎盖下 Rascal 可以使用瞬态可变状态直到列表理解完成,而 for 循环替代方案不假设任何内容并且仅使用不可变内部 API。