为什么“没有函数子句匹配”,即使将四个参数传递给arity为4的函数?

时间:2014-03-14 23:37:39

标签: erlang

这是我的问题代码:

-module(test).
-export([seed_matrix2/0, take_row_and_column/4]).


seed_matrix2() ->
    [0, 0, 1, 0,
     4, 0, 0, 0,
     0, 0, 0, 2,
     0, 4, 0, 0].

take_row_and_column(R, C, AnsMatrix, SideLen) ->
    RowVector = [ V || X <- lists:seq(0, SideLen-1), V <- lists:nth(R*SideLen+X, AnsMatrix) ],
    ColVector = [ V || X <- lists:seq(0, SideLen-1), V <- lists:nth(X*SideLen+C, AnsMatrix) ],
    {RowVector, ColVector}.

这是我调用函数test:take_row_and_column的错误消息:

74> test:take_row_and_column(1, 2, test:seed_matrix2(), 4).
** exception error: no function clause matching 
                    test:'-take_row_and_column/4-lc$^1/1-1-'(0) (/private/tmp/test.erl, line 12)
     in function  test:take_row_and_column/4 (/private/tmp/test.erl, line 12)

当我传递的参数数量不正确或者无法满足类型防护时,我通常会得到这个。我不明白为什么这段代码会触发no function clause matching

以下是erl的版本横幅:

Erlang R16B03 (erts-5.10.4) [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Eshell V5.10.4  (abort with ^G)

2 个答案:

答案 0 :(得分:4)

有问题的失败函数是编译器为列表推导生成的函数(注意名称中的“-lc $ ...”)。看起来这是因为你的生成器V&lt; - lists:nth(...,Matrix)试图从非列表中选择一个数字V,因为列表:nth / 2将从列表中返回第n个整数。像V&lt; - [lists:nth(...)]一样编写生成器应该可以工作。

答案 1 :(得分:2)

以下是修复:

take_row_and_column(R, C, AnsMatrix, SideLen) ->
    RowVector = [ lists:nth((R-1)*SideLen+X, AnsMatrix) || X <- lists:seq(1, SideLen-1) ],
    ColVector = [ lists:nth((X-1)*SideLen+C, AnsMatrix) || X <- lists:seq(1, SideLen-1) ],
    {RowVector, ColVector}.  

有问题的代码存在两个问题:

1)lists:seq(0, ...)应该是lists:seq(1, ...)lists:nth()不喜欢零值

2)erlang不喜欢V<-...部分。需要将整个lists:nth()调用移至||

的左侧