在Erlang中,是否有一种方法可以对枚举的原子集进行模式匹配?

在Erlang中,是否有一种方法可以对枚举的原子集进行模式匹配?,erlang,pattern-matching,Erlang,Pattern Matching,我目前正在学习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}. 不过,我想知道,有没有语法可以告

我目前正在学习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}.

我查阅了有关模式匹配的文档,但找不到类似的内容。

目前没有直接的方法将原子列表指定为模式

在你的情况下,你可以使用护卫,但它几乎不短

b_and(true, true) -> true;
b_and(A, B) when A =:= true or A =:= false,
                 B =:= true or B =:= false ->
    false.
顺便说一句,如果用其他任何方法调用函数都会出错,那么通常会关闭error子句


您可以使用这个解析转换,它将为警卫提供一个in()形式。问题是它是否值得,仅仅因为这样一个小的、不经常使用的具有解析转换的功能似乎有点重。

在这种特殊情况下,您可以使用
is_boolean
函数,它为原子
true
false
返回
true
,对于其他所有内容,
false

b_and(true, true) ->
  true;
b_and(A, B) when is_boolean(A), is_boolean(B) ->
  false;
b_and(_, _) ->
  {error, invalid_object}.

我只想强调@PeerStritzinger对error子句的评论。您肯定应该不要在
b_和/2
中有错误子句!如果使用非布尔参数调用它,则应生成错误。通常情况下,类型错误确实/应该会生成异常,大多数库都遵循此规则。

仅就如何处理类似问题给出不同的答案:


但是,再次强调,您确实不应该在这里屏蔽无效参数,除非您希望使用错误的参数调用,并且希望返回错误消息而不是异常。

您可以编写此代码,它应该可以

b_and(true,true) -> true ;
b_and(A,B) when is_boolean(A),is_boolean(B) -> false.

正如佩尔·斯特里辛格(Peer Stritzinger)所说,如果用错误的参数调用,就让它崩溃,并确保用布尔值调用它。

非常感谢。这就是您所指的解析转换吗?没错,根据@Kaos建议更新我的答案:你绝对不应该在b_和/2中有错误子句!如果使用非布尔参数调用它,则应生成错误。一般来说,类型错误确实/应该会生成异常,大多数库都遵循这一规则。Robert,这更适合作为Peer答案的注释,因为它本身不是答案。。作为评论,我会投赞成票:)嗨,为什么不简单:b_和(对,b)->布尔(b);b_和(false,u)->false。bool(true)->true;bool(false)->false。这可能是我们更喜欢的方式,但是对于
b_和(false,foo)
(正如我在回答的结束语中试图暗示的那样),您不会得到
{error,invalid_object}
b_and(true,true) -> true ;
b_and(A,B) when is_boolean(A),is_boolean(B) -> false.