Haskell platform 如何在Haskell中创建运算符?

Haskell platform 如何在Haskell中创建运算符?,haskell-platform,haskell,haskelldb,Haskell Platform,Haskell,Haskelldb,制作一个三元逻辑表,我想为一个操作符创建我自己的函数,我将调用 举个例子,我想这样做,但那是不对的。正确的方法是什么 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

制作一个三元逻辑表,我想为一个操作符创建我自己的函数,我将调用

举个例子,我想这样做,但那是不对的。正确的方法是什么

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
数据三元=T | F | M
推导(等式、显示、Ord)
::三值->三值->三值
tf=F
T=T
T M=M
F=T
F T=F
F M=M
mf=M
mt=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
()::三元->三元->三元
()T F=F
()T=T
()T M=M
()F=T
()F T=F
()F M=M
()mf=M
()mt=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
()::三元->三元->三元
tf=F
T=T
T M=M
F=T
F T=F
F M=M
mf=M
mt=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
-}
——工作原理:
()::Int->Int->Int
a b=a+b
--不起作用:
{-
::Int->Int->Int
a b=a+b
-}
--作品:
字母::Int->Int->Int
字母a b=a+b
--不起作用:
{-
(字母)::Int->Int->Int
a字母b=a+b
-}
不过,我保证-Haskell非常值得学习这些复杂的规则。

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

(<=>) :: Ternary -> Ternary -> Ternary
T <=> T = T
F <=> F = T
M <=> M = T
M <=> _ = M
_ <=> M = M
_ <=> _ = F
()::三元->三元->三元
T=T
F=T
M=T
M=M
_M=M
__uf=F

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

data Ternary = T | F | M
deriving (Eq, Show, Ord)

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

(<=>) :: Ternary -> Ternary -> Ternary
x <=> y = fromEnum $ rem (toEnum x * toEnum y) 3
数据三元=T | F | M
推导(等式、显示、Ord)
()::三元->三元->三元
x y=如果x==y,那么T else max x y
如果您碰巧更改了它,使
M==M
,则可以执行以下操作:

data Ternary = T | F | M
deriving (Eq, Show, Ord)

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

(<=>) :: Ternary -> Ternary -> Ternary
x <=> y = fromEnum $ rem (toEnum x * toEnum y) 3
数据三元=M | T | F
派生(等式、显示、Ord、枚举)
()::三元->三元->三元
x y=fromEnum$rem(toEnum x*toEnum y)3

作为旁注,
M
应该是
M
而不是
T
。但这取决于你的“可能”语义。别忘了你可以通过使用
infixl
infixr
…来设置算术和关联性。这对我来说并不简单。这就是为什么我有一个
(按行)
。然而,清晰度是有争议的。我可以更好地看到代码,因为我被迫推断它实际上做了什么,而不是看一个原始的列表定义。但那就是我。我觉得更简单,我可以很快看到,如果它们相等,那么返回真,如果它们不相等,但是一个是可能,那么返回可能,如果它们不相等,并且不涉及可能,那么返回假。唯一让我感到惊讶的是
M
T
部分。有没有办法创建类似
cons操作符的东西?
cons操作符具有此特殊功能,它将右侧的所有内容都视为一个列表。我一直在尝试重新创建
操作符,但是它总是需要在右边加括号。@ClarkGaebel:也许还应该提到
infix
。@cmcdragokai您可以用以下方法自己做同样的事情:
data List a=Nil | a:-List a
,然后是关键部分:
infixr 5:
。不必是5,但这是列表的优先级,只需是
infixr
,而不是
infixl
infix
<代码>infixl 9是默认值