如何修复 Erlang 中不正确的列表?

How can I repair an improper list in Erlang?

我不小心做了(相当于)下面的事情:

lists:foldl(fun(X, Acc) -> [X|Acc] end, 0, List).

注意累加器的非列表初始值。

这导致列表不正确。这意味着 length 等对它不起作用。

考虑到我的 "equivalent of" 花了一个小时才 运行,我不想再 运行 它,我该如何修复我不正确的列表?

有关不正确列表及其导致的问题的更简单示例:

1> L = [1|[2|[3|4]]].
[1,2,3|4]
2> length(L).
** exception error: bad argument
     in function  length/1
        called as length([1,2,3|4])

对于我遇到的简单情况,非嵌套的不正确列表,我不想要额外的项目(因为它应该是一个空列表并且没有任何意义),这就可以了:

Fix = fun F([H|T], A) when is_list(T) -> F(T, [H|A]);
          F([H|_], A) -> F([], [H|A]);
          F([], A) -> lists:reverse(A)
      end.
Fix(L, []).

这是一个可能的方法:

Lister = fun L([], Acc)                -> lists:reverse(Acc);
             L([[_ | _] = H | T], Acc) -> L(T, [L(H, []) | Acc]);
             L([[] | T], Acc)          -> L(T, Acc);
             L([H | T], Acc)           -> L(T, [H | Acc]);
             L(X, Acc)                 -> L([], [X | Acc])
         end.

L = [[[1,[1|2]],1|2],1|[2|[3|4]]].

Lister(L, []).
% output [[[1,[1,2]],1,2],1,2,3,4]

您必须使用列表进行 ACC

lists:foldl(fun(X, Acc) -> [X|Acc] end, 0, [1,2,3]).

结果 => [3,2,1|0] 但是如果你在列表中使用 [0] 作为 ACC 参数:foldl/3 函数如下

lists:foldl(fun(X, Acc) -> [X|Acc] end, [0], [1,2,3]).

结果 => [3,2,1,0]

如果你想保留"improper tail",这就足够了:

Fix = fun Fix([H | T]) -> [H | Fix(T)];
          Fix(T) -> [T]
      end.