使用中缀运算符连接列表中的所有元素

Connecting all elements in list with infix operator

所以我有一个列表可以说 [t, f, f, t, f] 和一个中缀运算符 <==>.我想连接元素,因此最终结果将如下所示 t <==> f <==> f <==> t <==> f 。我遇到的问题是我得到了这个结果 t <==> (f <==> (f <==> (t <==> f))) .我知道为什么会发生这种情况,因为复活 returns 所有以前的元素,但我不知道如何解决它。

这是我的代码:

fun connect(l) =
    case l of
      x::[] => x
      | x::xs => x1 <==> connect(xs);

the end result will look like this t <==> f <==> f <==> t <==> f.

problem is that i get this result t <==> (f <==> (f <==> (t <==> f)))

x <==> y <==> z 可能表示 (x <==> y) <==> zx <==> (y <==> z).

如果向一侧折叠有问题,请尝试向另一侧折叠:

fun connectLeft (x::xs) = foldl (op <==>) x xs
fun connectRight (x::xs) = foldr (op <==>) x xs

您可以看到 foldl and foldr 是如何实现的。

或者你可以看folds as structural transformations(维基百科)的插图。


编辑: 假设 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 returns 一个 bool,那么也许你的意思是在这里使用 andalso
  • 既然 connect 应该 returns 是 bool 或某个用户​​定义的真值,那么可能 connect [x] = x,但也可能不是。
  • 无论如何,connect []应该考虑:这里是否有一个好的默认值,以便该函数不会在空列表上崩溃?

如果您想使用列表组合器(如 mapfoldl 等)而不是手动递归来编写此代码,您可以做的是:

  1. 将输入列表转换为对列表,因此 [x, y, z] 变为 [(x, y), (y, z)]。有一个名为 zip 的 SML 函数,隐藏在库 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)]
    
  2. 在配对列表上调用 map (op <==>)

  3. 用一些 && 运算符折叠结果。