SML不能使用foldr来反转列表

时间:2014-09-27 20:31:05

标签: sml

我正在尝试使用foldr来反转列表,如下所示

 fun revl2 x = foldr(fn(x,y)=>y@[x],[]);

并试试这个

 fun  revl1 x = foldr (op @) []x;

和这个

 fun  revl1 x = foldr (op ::) []x;

它不起作用,我不知道为什么。

谢谢。

2 个答案:

答案 0 :(得分:1)

foldr就是我们所说的curried函数。这意味着它不是将其参数作为元组,而是接受一个参数然后返回另一个curried函数,该函数以相同的方式获取剩余的参数。在这种情况下,所有这些意味着您需要将其称为foldr f init list,而不是foldr (f, init, list)

这就是为什么你的第一次尝试是错误的(事实上你根本没有提供列表参数)。在第二次和第三次尝试中,您确实使用了正确的语法来调用它,但是您不再提供正确的函数。

赋予foldr的函数有两个参数:列表的元素和累加器的当前值。在您的情况下,累加器是一个列表,因此您需要提供一个函数,其中第一个参数是列表的元素,第二个参数是列表。在您的第二次尝试中,您提供了op @,其中包含两个列表,因此无效。

在您的第三次尝试中,您提供了op ::,它确实采用了元素和列表,但它在列表的开头添加了元素。由于foldr (op ?) init xs的结果为x1 ? x2 ? x3 ? ... ? xn ?? init,因此在这种情况下您会获得x1 :: x2 :: x3 :: ... :: xn :: [],这只是原始列表 - 没有任何内容被撤消。

因此,要解决此问题,您需要提供一个在列表末尾添加单个元素的函数。这正是你第一次尝试的功能所在,所以只需使用那个功能。

答案 1 :(得分:0)

foldr具有签名('a * 'b -> 'b) -> 'b -> 'a list -> 'b,并被调用为:

  

foldr f init [x1,x2,...,xn]       返回

f(x1, f(x2, ..., f(xn, init)...))

or init if the list is empty.

请注意,f必须是一个接受两个参数的函数。由于函数的最终结果是列表,因此两个元素都必须是列表。

使用foldr反转列表:

 List.foldr (fn(x,y) => y @ [x]) [] [1,2,3]

在参数[]周围放置x会创建必要的列表。