如何在Haskell中创建运算符



制作一个三元逻辑表,我想为一个将调用<=>的运算符制作自己的函数。

例如,我想这样做,但这是不对的。正确的方法是什么?

data Ternary = T | F | M
deriving (Eq,  Show, Ord)
<=> :: Ternary -> Ternary -> Ternary
<=> T F = F
<=> T T = T
<=> T M = M
<=> F F = T
<=> F T = F
<=> F M = M
<=> M F = M
<=> M T = M
<=> M M = T

只需在运算符周围添加括号:

(<=>) :: Ternary -> Ternary -> Ternary
(<=>) T F = F
(<=>) T T = T
(<=>) T M = M
(<=>) F F = T
(<=>) F T = F
(<=>) F M = M
(<=>) M F = M
(<=>) M T = M
(<=>) M M = T

这就把它从中缀形式变成了前缀形式。或者,你可以在定义中使用中缀:

(<=>) :: Ternary -> Ternary -> Ternary
T <=> F = F
T <=> T = T
T <=> M = M
F <=> F = T
F <=> T = F
F <=> M = M
M <=> F = M
M <=> T = M
M <=> M = T

带有符号的函数名与没有符号的函数名称具有不同的语法:

-- Works:
(<^>) :: Int -> Int -> Int
a <^> b = a + b
-- Doesn't work:
{-
<^> :: Int -> Int -> Int
<^> a b = a + b
-}
-- Works:
letters :: Int -> Int -> Int
letters a b = a + b
-- Doesn't work:
{-
(letters) :: Int -> Int -> Int
a letters b = a + b
-}

不过,我保证——哈斯克尔非常值得学习复杂的规则。

您可以简化(逐行)定义如下:

(<=>) :: Ternary -> Ternary -> Ternary
T <=> T = T
F <=> F = T
M <=> M = T
M <=> _ = M
_ <=> M = M
_ <=> _ = F

由于您有EqOrd,您可以执行以下操作:

data Ternary = T | F | M
deriving (Eq, Show, Ord)
(<=>) :: Ternary -> Ternary -> Ternary
x <=> y = if x == y then T else max x y

如果你碰巧把它改成M <=> M == M,那么你可以做以下事情:

data Ternary = M | T | F
deriving (Eq, Show, Ord, Enum)
(<=>) :: Ternary -> Ternary -> Ternary
x <=> y = fromEnum $ rem (toEnum x * toEnum y) 3

最新更新