2013-07-21 25 views
2

我目前正在接受Erlang,它的模式匹配是我在一段时间内看到的最酷的事情之一。一个小玩具功能,我在我的练习拿出如下:在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}. 

我已经通过模式匹配的文档看,但我找不到这样的事。

回答

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它会给你一个警卫的()形式。问题是如果它是值得的,只是对于这样一个小而不是经常使用的功能来说,解析变换看起来有点重量级。

+0

非常感谢。这是你所指的分析转换吗? https://github.com/mad-cocktail/gin –

+0

是的,更新我的回答 –

+1

根据@Kaos的建议:你绝对不应该在b_and/2中有一个错误子句!如果使用非布尔参数调用它,它应该会产生一个错误。通常,类型错误会/会产生异常,大多数类库遵循此规则。 – rvirding

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}. 
0

我只是想强调通过@PeerStritzinger发表的意见关于错误条款。您当然应该不是b_and/2有一个错误条款!如果使用非布尔参数调用它,它应该会产生一个错误。通常,类型错误会/会产生异常,大多数类库遵循此规则。

+0

罗伯特,这会更好地作为对彼得答案的评论,因为它本身不是答案。作为评论,我会投它:) – Kaos

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被称为并希望返回错误消息而不是异常。

+0

嗨,为什么不简单:b_and(true,B) - > bool(B); b_and(false,_) - > false。 bool(true) - > true; bool(false) - > false。 – niahoo

+0

这可能是我们比较喜欢的方式,但是你不会为'b_and(false,foo)'得到'{error,invalid_object}'(正如我在回答的最后一句中试图暗示的那样) 。 – Kaos

0

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

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

正如Peer Stritzinger所说,如果调用不合理的参数,让它崩溃并确保您用布尔值调用它。