我现在正在接收Erlang,它的模式匹配是我一段时间见过的最酷的事情之一。我在练习中提出的一个小玩具功能如下:
b_and(true, true) ->
true;
b_and(true, false) ->
false;
b_and(false, true) ->
false;
b_and(false, false) ->
false;
b_and(_, _) ->
{error, invalid_object}.
我想知道,是否有语法告诉模式中的变量只接受一组枚举原子?这样,我可以将它缩短为这样的东西:
b_and(true, true) ->
true;
% We've already satisfied the only true case
b_and(ENUM(true, false), ENUM(true, false)) ->
false;
b_and(_, _) ->
{error, invalid_object}.
我查看了关于模式匹配的文档,但我找不到这样的内容。
答案 0 :(得分:3)
目前没有直接的方法来指定原子列表作为模式。
在你的情况下,你可以使用一个后卫,但它几乎不会更短
b_and(true, true) -> true;
b_and(A, B) when A =:= true or A =:= false,
B =:= true or B =:= false ->
false.
如果用其他任何东西调用该函数是错误的,那么通常会关闭错误子句。
你可以使用这个解析变换https://github.com/mad-cocktail/gin,它会给你一个in()形式的守卫。问题是它是否值得,只是对于这样一个小而且不经常使用的具有解析变换的功能似乎有点重量级。
答案 1 :(得分:1)
在这种特殊情况下,您可以使用is_boolean
函数,它为原子true
和true
返回false
,并为其他所有内容返回false
:
b_and(true, true) ->
true;
b_and(A, B) when is_boolean(A), is_boolean(B) ->
false;
b_and(_, _) ->
{error, invalid_object}.
答案 2 :(得分:0)
我只想强调@PeerStritzinger关于错误条款的评论。你绝对应该 NOT 在b_and/2
中有错误条款!如果使用非布尔参数调用它,则应生成错误。通常类型错误会/应该生成异常,大多数库都遵循此规则。
答案 3 :(得分:0)
就如何处理这样的事情给出一个不同的答案:
b_and(true, B) -> bool(B);
b_and(false, B) -> bool(B, false).
bool(B) -> bool(B, B).
bool(true, Res) -> Res;
bool(false, Res) -> Res;
bool(_, _) -> {error, invalid_object}.
但是再一次,你真的不应该在这里屏蔽无效的参数,除非你期望用坏的args调用并且想要返回错误消息而不是异常。
答案 4 :(得分:0)
你可以写这个,它应该没问题。
b_and(true,true) -> true ;
b_and(A,B) when is_boolean(A),is_boolean(B) -> false.
正如Peer Stritzinger所说,如果被错误的论点召唤,请让它崩溃,并确保用布尔调用它。