我想学习Erlang,在书中我有练习: 编写一个模块boolean.erl,它接受逻辑表达式和布尔值(表示 作为原子true和false)并返回它们的布尔结果。功能 你写的应该包括b_not / 1,b_and / 2,b_or / 2和b_nand / 2。你不应该使用 逻辑结构和,或者,而不是,而是使用模式匹配来实现你的 目标。 从shell测试您的模块。调用导出函数的一些示例 你的模块包括:
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.
如何解决最后一个例子,我真的不明白。有帮助吗? 感谢。
答案 0 :(得分: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.
_
是不关心变量,它匹配任何内容并且永远不会被绑定。好吧,如果使用布尔值 BUT 调用,两个版本的行为都相同,如果使用非布尔值调用它们的行为会有所不同。在这种情况下,第二个返回true
,而第一个生成异常。通常最好在错误输入上生成异常,而不是让它通过并返回误导性答案,因此第一种选择是更好的解决方案。
写b_and
(和b_xor
)留给你。
很抱歉,如果这有点长,但模式匹配可能需要一些时间来适应。写下你期望的而不是如何测试它的概念与OO和命令式语言中的常见不同。 (我提供课程,这是一个常见的障碍)
答案 1 :(得分:2)
如果仅限于模式匹配b_not/1
,则应如下所示:
b_not(false) -> true;
b_not(true) -> false.
尝试将此想法用于其他功能。
提示:对于其他函数,您不需要为每种可能的情况编写子句。