sml - 使用中缀运算符连接列表中的所有元素
问题描述
所以我有一个列表,可以说[t, f, f, t, f]和一个中缀运算符<==>。我想连接元素,因此最终结果将如下所示t <==> f <==> f <==> t <==> f。我遇到的问题是我得到了这个结果t <==> (f <==> (f <==> (t <==> f)))。我知道为什么会发生这种情况,因为 resursion 返回所有以前的元素,但我不知道如何解决它。
这是我的代码:
fun connect(l) =
case l of
x::[] => x
| x::xs => x1 <==> connect(xs);
解决方案
最终结果将如下所示t <==> f <==> f <==> t <==> f。
问题是我得到了这个结果t <==> (f <==> (f <==> (t <==> f)))
x <==> y <==> z
可能意味着(x <==> y) <==> z
或者x <==> (y <==> z)
。
如果折叠到一侧有问题,请尝试折叠到另一侧:
fun connectLeft (x::xs) = foldl (op <==>) x xs
fun connectRight (x::xs) = foldr (op <==>) x xs
你可以看到是如何实现的foldl
。foldr
或者您可以将折叠的插图视为结构转换(维基百科)。
编辑:假设x <==> y <==> z表示(x <==> y) && (y <==> z):
fun connect [] = ?
| connect [x] = ?
| connect [x,y] = x <==> y
| connect (x :: y :: rest) =
(x <==> y) && connect (y :: rest)
&&
不是 SML 内置的逻辑与运算符的名称,称为andalso
. 如果x <==> y
返回 abool
,那么也许你的意思是在andalso
这里使用。- 既然
connect
应该返回一个bool
或一些用户定义的真实值,那么可能connect [x] = x
,但可能不是。 - 在任何情况下,
connect []
都应该考虑:这里是否有一个很好的默认值,以便函数不会在空列表上崩溃?
如果您想使用列表组合符(如map
,foldl
等)而不是手动递归来编写此代码,您可以做的是:
将输入列表转换为对列表,因此
[x, y, z]
变为[(x, y), (y, z)]
。有一个名为 的 SML 函数zip
,隐藏在库中ListPair
……一些示例可能暗示如何执行此操作:ListPair.zip [x1,x2,x3] [y1,y2,y3] = [(x1,y1), (x2,y2), (x3,y3)] ListPair.zip [x1,x2,x3] [x1,x2,x3] = [(x1,x1), (x2,x2), (x3,x3)] ListPair.zip [x1,x2,x3] [y2,y3] = [(x1,y2), (x2,y3)]
调用
map (op <==>)
对列表。用一些运算符折叠结果
&&
。