2

我想学习 Erlang,在书中我有一个练习:编写一个模块 boolean.erl,它接受逻辑表达式和布尔值(表示为原子 true 和 false)并返回它们的布尔结果。您编写的函数应包括 b_not/1、b_and/2、b_or/2 和 b_nand/2。您不应该使用逻辑结构 and、or 和 not,而是使用模式匹配来实现您的目标。从外壳测试您的模块。在模块中调用导出函数的一些示例包括:

bool:b_not(false) ⇒ true
bool:b_and(false, true) ⇒ false
bool:b_and(bool:b_not(bool:b_and(true, false)), true) ⇒ true.

所以到目前为止我想出的最好的解决方案是:

-module(b).

-export([b_not/1,b_and/2,b_or/2]).


b_not(false) -> false /= true.
%%%
b_and(false, false) -> false;
b_and(X, Y) -> X == Y.    
%%%
b_or(true, true) -> true;
b_or(X, Y) -> X /= Y.

最后一个例子怎么解决,我真的不明白。有什么帮助吗?谢谢。

4

2 回答 2

4

我有点不同意@hdima 所说的话。本练习的目标练习模式匹配,不使用任何运算符。模式匹配的最佳方法是写下每个案例。那么b_or这些论点有哪些不同的可能情况呢?有 4 个:true, true; true, false; false, true; 和false, false. 因此,只需将每个案例写成一个单独的子句,返回正确的值:

b_or(true, true) -> true;
b_or(true, false) -> true;
b_or(false, true) -> true;
b_or(false, false) -> false.

因此,查看此答案您可能会想得很好,因为许多情况都是相同的,为什么不将其优化为:

b_or(false, false) -> false;
b_or(_, _) -> true.

_无关变量,它匹配任何东西并且永远不会被绑定。好吧,如果使用布尔值调用,两个版本的行为相同,如果使用非布尔值调用,它们的行为会有所不同。在这种情况下,第二个返回true,而第一个生成异常。通常最好在错误输入时生成异常,而不是让它通过并返回误导性的答案,因此第一种选择是更好的解决方案。

写作b_and(和b_xor)留给你。

对不起,如果这有点长,但模式匹配可能需要一些时间来适应。写下您的期望而不是如何测试它的概念与 OO 和命令式语言中常见的概念不同。(我提供课程,这是一个常见的障碍)

于 2013-09-18T22:31:51.600 回答
2

如果您仅限于模式匹配b_not/1,则应如下所示:

b_not(false) -> true;
b_not(true) -> false.

尝试将此想法用于其他功能。

提示:对于其他功能,您不需要为每种可能的情况编写子句。

于 2013-09-18T21:35:37.923 回答