我正在尝试使用foldr
来反转列表,如下所示
fun revl2 x = foldr(fn(x,y)=>y@[x],[]);
并试试这个
fun revl1 x = foldr (op @) []x;
和这个
fun revl1 x = foldr (op ::) []x;
它不起作用,我不知道为什么。
谢谢。答案 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
会创建必要的列表。