3

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

我浏览了有关模式匹配的文档,但找不到类似的东西。

4

5 回答 5

4

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

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

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() 形式的警卫。问题是它是否值得,只是对于这么少且不经常使用的具有解析转换的功能似乎有点重量级。

于 2013-07-21T09:57:28.630 回答
1

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

b_and(true, true) ->
  true;
b_and(A, B) when is_boolean(A), is_boolean(B) ->
  false;
b_and(_, _) ->
  {error, invalid_object}.
于 2013-07-21T11:29:08.677 回答
0

我只想强调@PeerStritzinger 关于错误条款的评论。你绝对应该在b_and/2!如果使用非布尔参数调用它应该会产生错误。通常类型错误确实/应该产生异常,大多数库都遵循此规则。

于 2013-07-21T15:06:42.260 回答
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}.

但是话又说回来,你真的不应该在这里屏蔽无效参数,除非你希望用错误的参数调用并希望返回错误消息而不是异常。

于 2013-07-21T18:44:09.420 回答
0

你可以写这个,它应该没问题。

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

正如 Peer Stitzinger 所说,如果用错误的参数调用,让它崩溃并确保你用布尔值调用它。

于 2013-07-22T10:15:59.787 回答