如何在Haskell中实现并使用异或运算完成三角形类型判断
Haskell 异或运算符实现与三角形类型判断方案
异或函数转运算符的两种实现方式
你编写的异或逻辑本身是正确的,要将其作为运算符使用有两种可选方案:
- 直接将函数名用反引号包裹,即可作为中缀运算符调用:
exclusiveOR :: Bool -> Bool -> Bool exclusiveOR a b = (a || b) && not (a && b) -- 调用示例:两个布尔值a、b做异或运算 res = a `exclusiveOR` b
- 定义专属运算符别名,你可以选择Unicode符号或者ASCII符号作为异或运算符:
-- 使用Unicode符号⊕作为异或运算符 (⊕) :: Bool -> Bool -> Bool a ⊕ b = (a || b) && not (a && b) -- 如果不想使用Unicode,也可以自定义ASCII运算符,比如<+> (<+>) :: Bool -> Bool -> Bool a <+> b = (a || b) && not (a && b) -- 调用示例 res = a ⊕ b res2 = a <+> b
修正后的三角形类型判断函数
你当前的函数骨架存在两个需要调整的点:
- 三角形合法性判断只校验了
a+b<c,漏了另外两组两边之和大于第三边的判断 - 等边三角形的判断需要放在等腰判断之前,否则等边的情况会先触发等腰的判断逻辑
使用异或运算符实现的完整代码如下:
-- 定义异或运算符 (<+>) :: Bool -> Bool -> Bool a <+> b = (a || b) && not (a && b) triangle :: (Ord a, Eq a) => a -> a -> a -> String triangle a b c | a + b <= c || a + c <= b || b + c <= a = error "Not a triangle" | a == b && b == c = "equilateral triangle" -- 前面已排除三边全相等的情况,异或结果为真等价于恰好一组边相等 | (a == b) <+> (b == c) <+> (a == c) = "isosceles triangle" | otherwise = "scalene triangle"
无需自定义异或的替代实现
如果不想额外定义异或运算符,也可以通过统计相等边对的数量实现,逻辑更直观:
triangle :: (Ord a, Eq a) => a -> a -> a -> String triangle a b c | a + b <= c || a + c <= b || b + c <= a = error "Not a triangle" | eqPairCount == 3 = "equilateral triangle" | eqPairCount == 1 = "isosceles triangle" | otherwise = "scalene triangle" where eqPairCount = length [() | (x,y) <- [(a,b), (b,c), (a,c)], x == y]
内容的提问来源于stack exchange,提问作者Heil
相关产品推荐
相关产品推荐

