Comment puis-je créer un opérateur Haskell?
-
28-10-2019 - |
Question
Faire une table logique ternaire, et je voudrais faire ma propre fonction pour un opérateur que je vais appeler <=>
.
Ainsi, par exemple, je veux faire, mais qui ne va pas. quelle est la bonne façon de le faire?
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
La solution
Il suffit d'ajouter des parenthèses autour de votre opérateur:
(<=>) :: 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
Cette forme de tour il infix à la forme de préfixe. Sinon, vous pouvez simplement utiliser infix dans la définition:
(<=>) :: 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
Autres conseils
Les noms de fonctions avec symboles ont une syntaxe différente que ceux sans:
-- 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
-}
Je promets, bien que - Haskell vaut bien apprendre les règles complexes
.Vous pouvez simplifier (ligne par ligne) la définition comme suit:
(<=>) :: Ternary -> Ternary -> Ternary
T <=> T = T
F <=> F = T
M <=> M = T
M <=> _ = M
_ <=> M = M
_ <=> _ = F
Puisque vous avez Eq
et Ord
, vous pouvez faire ce qui suit:
data Ternary = T | F | M
deriving (Eq, Show, Ord)
(<=>) :: Ternary -> Ternary -> Ternary
x <=> y = if x == y then T else max x y
Si vous ne vous arrive de changer de sorte que M <=> M == M
, alors vous pouvez faire ce qui suit:
data Ternary = M | T | F
deriving (Eq, Show, Ord, Enum)
(<=>) :: Ternary -> Ternary -> Ternary
x <=> y = fromEnum $ rem (toEnum x * toEnum y) 3