在案例模式匹配内调用函数是非法模式?

时间:2017-01-05 00:16:15

标签: erlang pattern-matching

-module(erltoy).
-compile(export_all).

isFive(5) -> true;
isFive(_) -> false.

foo(X) ->
 case X of
  isFive(X) -> true;
  3 -> false;
  _ -> nope
end.



1> c(erltoy).
erltoy.erl:9: illegal pattern
error

我不能将函数作为模式匹配的一部分来调用吗?

2 个答案:

答案 0 :(得分:2)

isFive(X) - > true; 包含无法在编译时计算为常量的表达式,因此不是有效的pattern。如果算术表达式满足以下两个条件,则可以在模式中使用该算术表达式:

  • 它仅使用数字或按位运算符。
  • 在编译时,可以将其值评估为常量。

请参阅Erlang参考手册

中的此示例
case {Value, Result} of
    {?THRESHOLD+1, ok} -> ...

答案 1 :(得分:2)

要完成@byaruhaf答案,在编译时,案例子句的左侧部分不需要是常量。以下代码是有效的,显然,Temp在编译时是未知的(但foo(5)计算为nope!)。

-module(erltoy).
-compile(export_all).

isFive(5) -> true;
isFive(_) -> false.

foo(X) ->
 Temp = isFive(X),
 case X of
  Temp -> true;
  3 -> false;
  _ -> nope
end.

甚至没有必要在执行时绑定左边部分,例如,这也是有效的,并且I在案例评估之前未绑定,并在模式匹配期间绑定:

get_second_element_of_3_terms_tuple_if_pos_integer(X) ->
  case X of
    {_,I,_} when is_integer(I), I>0 -> {true,I};
    _ -> false
  end.

案例的左侧部分必须是带有可选保护序列的有效模式。

有效模式是一个可能包含未绑定变量的erlang术语,如果它们遵守2个条件,它也可能包含算术表达式

  • 它仅使用数字或按位运算符。
  • 在编译时,可以将其值评估为常量。

保护序列的定义给出了there in erlang documentation

最后一点,在您的示例中,通常的erlang编码测试函数的方法是使用不同的函数头,就像使用isFive / 1定义一样。