在Haskell中(在Prolog / Erlang中非常相似),我们可以在列表上定义一个长度函数:
length [] = 0
length (x:xs) = 1 + length xs
在Rascal中,我能够使用以下方法创建这样的定义:
int length([]) = 0;
int length([x,xs*]) = 1 + length(xs);
" *"消失在递归长度的右侧。我知道它可能存在这个原因,但我无法理解。是否有更好的方法在Rascal中使用模式匹配在列表上定义递归函数?
答案 0 :(得分:2)
我想解决您的问题的各个方面:
*
标记,以表明这一点。我们处于过渡阶段,我们正在从后缀*转移到前缀*。所以第二条规则可以(并且将来应该)写成:
int length([x,*xs]) = 1 + length(xs);
您可能想要探索可用于编写各种类似折叠函数的 reducer表达式:
int length(list[int] xs) = ( 0 | it + 1 | x <- xs );
它由三部分组成:
it
设置为此初始值。it
的表达式,此处为:it + 1
。它的效果为it = it + 1
。[*x, a]
:匹配列表末尾的元素[*x, *x]
:将列表分成两等份[*a, x, *b, x, *c]
:找到两个重复的元素int length([x,*xs]) = 1 + length([*xs]);
,当然这也是一般化的,所以这也是可能的:[*xs, 2, *xs]
其中*
运算符只是删除了一层列表嵌套。