SML can';不要使用foldr来反转列表

SML can';不要使用foldr来反转列表,sml,Sml,我正在尝试使用foldr来反转如下列表 fun revl2 x = foldr(fn(x,y)=>y@[x],[]); 试试这个 fun revl1 x = foldr (op @) []x; 还有这个 fun revl1 x = foldr (op ::) []x; 这不管用,我不知道为什么 谢谢。具有签名('a*'b->'b)->'b->'a列表->'b,并被调用为: foldr f init[x1,x2,…,xn] 返回 f(x1, f(x2, ..., f(xn,

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

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

 fun  revl1 x = foldr (op @) []x;
还有这个

 fun  revl1 x = foldr (op ::) []x;
这不管用,我不知道为什么

谢谢。

具有签名
('a*'b->'b)->'b->'a列表->'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
周围放置
[]
将创建必要的列表。

foldr
就是我们所称的curried函数。这意味着它不将其参数作为元组,而是获取一个参数,然后返回另一个以相同方式获取其余参数的curried函数。在本例中,这意味着您需要将其称为
foldr f init list
,而不是
foldr(f,init,list)

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

赋予
foldr
的函数有两个参数:列表的一个元素和累加器的当前值。在本例中,累加器是一个列表,因此需要提供一个函数,其中第一个参数是列表的元素,第二个参数是列表。在第二次尝试中,您提供了
op@
,它包含两个列表,因此不起作用

在第三次尝试中,您提供了
op::
,它接受一个元素和一个列表,但它将元素添加到列表的开头。因为
foldr(op?)init xs
的结果是
x1?x2?x3?xn??init
,您将得到
x1::x2::x3:::xn::[]
在本例中,它只是原始列表-没有任何内容被颠倒


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

“请注意,f必须是一个接受两个相同类型参数的函数。”这根本不是真的。第一个参数的类型为“a”,第二个参数的类型为“b”。这些不必是相同的类型。事实上,他们不在这里。如果x的类型与y相同,那么它们都是列表,并且不必在x的周围添加括号。还要注意的是,你根本没有从OP的尝试中改变功能——他已经把那个部分做对了。谢谢,但我有一个问题要问你。什么是List.folder?
List.foldr
是SML Basis库[在我的答案中链接]中的
foldr
的完全限定名。完全限定名称更有可能在更广泛的特定SML安装中使用,因此我出于习惯键入它。