【问题标题】:Our own tuple_to_list() function我们自己的 tuple_to_list() 函数
【发布时间】:2016-11-29 19:56:32
【问题描述】:

我需要编写自己的 tuple_to_list() 函数(是的,来自 the 书)并在我的 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

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

【问题讨论】:

    标签: erlang


    【解决方案1】:

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

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

    【讨论】:

    • 啊!所以head mismatch 实际上是在抱怨,因为它认为所有三个语句都是同一个函数的一部分!非常感谢。 :-)
    【解决方案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) 洗牌时注意点和分号。 :D
    【解决方案3】:

    当您对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), []).
    

    注意我如何将递减索引用于尾递归函数。

    【讨论】:

      猜你喜欢
      • 2012-01-12
      • 1970-01-01
      • 2018-06-14
      • 1970-01-01
      • 1970-01-01
      • 2013-07-16
      • 1970-01-01
      • 1970-01-01
      • 2018-05-04
      相关资源
      最近更新 更多