如何确定 true/false 然后 return 一个函数

How to determine if true/false and then return a function

我有不同逻辑运算符的真值表;

truthtable a1
 | a1 == "mynot"   = [(p,q,r,s) | p <- [0,1], q <- [0,1], let r = mynot p, s <- ["mynot"]]
 | a1 == "myand"   = [(p,q,r,s) | p <- [0,1], q <- [0,1], let r = myand p q, s <- ["myand"]]
 | a1 == "myor"    = [(p,q,r,s) | p <- [0,1], q <- [0,1], let r = myor p q, s <- ["myor"]]
 | a1 == "myimply" = [(p,q,r,s) | p <- [0,1], q <- [0,1], let r = myimply p q, s <- ["myimply"]]

现在我必须创建一个函数 (equiv) 来确定两个运算符的行为是否相同,如果不同则给出一个反例。所以对于 equiv "myimply" "myimply" 它应该确定它是等价的,但是对于 equiv "myimply" "myor" 它应该调用函数 counterEx 它给出了一个反例(运算符不相同)。

现在我有了这个:

equiv a1 a2
 | truthtable a1 == truthtable a2 = True
 | otherwise = counterEx a1 a2

counterEx a1 a2 = truthtable a1 ++ truthtable a2

当然,equiv 有不同的结果,因此是不可能的。但是,我真的不知道如何给出一个更好的反例(而不是只给出所有可能性,而您只会看到不一样的地方)。同样,我真的不知道如果真值表不等价,我该如何调用函数 counterEx,但如果真值表确实相同,我只能确定它们相同。

这里最惯用的解决方案是使用自定义 return 数据类型

type TTable = [(Int,Int,Int,Int)]

data EquivResult
  = Equivalent
  | NotEquivalent TTable

equiv :: TTable -> TTable -> EquivResult
equiv a1 a2
 | truthtable a1 == truthtable a2 = Equivalent
 | otherwise                      = NotEquivalent (counterEx a1 a2)

也可以使用 Maybe TTable 而不是定义自定义 EquivResult,但不太明显 Nothing 表示 "equivalent",而 Just _将意味着“_ 是一个反例”。

equiv :: TTable -> TTable -> Maybe TTable
equiv a1 a2
 | truthtable a1 == truthtable a2 = Nothing
 | otherwise                      = Just (counterEx a1 a2)

顺便问一下,为什么要使用整数 01 作为布尔值?为什么不是 FalseTrue 类型 Bool。对布尔值使用 Int 感觉很奇怪,并且允许无效值,例如 2.

(作为一般建议,我建议通过声明其类型来开始编写每个函数。类型签名对于尽快检测潜在错误以及帮助编译器生成更好的错误消息非常重要。)