我需要编写自己的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
我不知道"头部不匹配"有,为什么函数未定义(我已将它添加到模块导出语句中,但我怀疑这与导出语句有很大关系)?
答案 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)
另一个答案解释了如何解决这个问题,但不是原因。所以:;
在函数定义子句之后意味着下一个子句继续定义,就像case
和if
分支一样。 head mismatch
表示在一个定义中包含具有不同名称和/或参数数量的函数子句。出于同样的原因,使用以.
结尾的子句后跟另一个具有相同名称和参数计数的子句是错误的。
出于不同的原因需要更改子句的顺序,而不是因为错误。始终按顺序检查子句(同样,对于case
和if
),并且您的第一个子句已匹配任何两个参数。所以第二个永远不会被使用。
答案 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), []).
注意我如何使用递减索引来实现尾递归函数。