我们自己的tuple_to_list()函数

时间:2016-07-26 08:55:13

标签: erlang

我需要编写自己的tuple_to_list()函数(是的,来自 一书),并在我的erl文件中提出了这个问题:

%% Our very own tuple_to_list function! %%
% First, the accumulator function
my_tuple_to_list_acc(T, L) -> [element(1, T) | L];
my_tuple_to_list_acc({}, L) -> L;
% Finally, the public face of the function
my_tuple_to_list(T) -> my_tuple_to_list_acc(T, []).

然而,当我编译它时,我在shell中得到以下错误:

28> c(lib_misc).
lib_misc.erl:34: head mismatch
lib_misc.erl:2: function my_tuple_to_list/1 undefined
error

我不知道"头部不匹配"有,为什么函数未定义(我已将它添加到模块导出语句中,但我怀疑这与导出语句有很大关系)?

3 个答案:

答案 0 :(得分:2)

这些错误意味着您没有结束my_tuple_to_list_acc / 2的定义。 您应该更改前两个代码行的顺序,并在它们之后添加点。

my_tuple_to_list_acc({}, L) -> L;
my_tuple_to_list_acc(T, L) -> [element(1, T) | L].

答案 1 :(得分:2)

另一个答案解释了如何解决这个问题,但不是原因。所以:;在函数定义子句之后意味着下一个子句继续定义,就像caseif分支一样。 head mismatch表示在一个定义中包含具有不同名称和/或参数数量的函数子句。出于同样的原因,使用以.结尾的子句后跟另一个具有相同名称和参数计数的子句是错误的。

出于不同的原因需要更改子句的顺序,而不是因为错误。始终按顺序检查子句(同样,对于caseif),并且您的第一个子句已匹配任何两个参数。所以第二个永远不会被使用。

答案 2 :(得分:0)

如果您对tuple_to_list/1实施工作感兴趣

1> T2L = fun (T) -> (fun F(_, 0, Acc) -> Acc; F(T, N, Acc) -> F(T, N-1, [element(N, T)|Acc]) end)(T, tuple_size(T), []) end.
#Fun<erl_eval.6.50752066>
2> T2L({}).
[]
3> T2L({a,b,c}).
[a,b,c]

或在模块中

my_typle_to_list(_, 0, Acc) -> Acc;
my_typle_to_list(T, N, Acc) ->
    my_typle_to_list(T, N-1, [element(N, T)|Acc]).

my_typle_to_list(T) ->
    my_typle_to_list(T, tuple_size(T), []).

注意我如何使用递减索引来实现尾递归函数。