learn - syntax haskell
AnulaciĆ³n(==) en Haskell (2)
Si desea un comportamiento personalizado para Op
, pero un comportamiento regular para todas las demás variantes de su tipo de datos, deberá dividir Op
en su propio tipo.
Por ejemplo:
data Exp
= Con Int
| Var String
| Input
| PrimOp Op
deriving (Show,Eq)
data Op = Op Opkind Exp Exp
deriving Show
data Opkind
= Plus | Minus | Mult | Div | More | Equal
deriving (Show,Eq)
-- equality on (symbolic) functions, perhaps?
instance Eq Op where
(Op a _ _) == (Op b _ _) = a == b
Definamos todas las expresiones estructuralmente iguales, excepto para aplicaciones de funciones a argumentos, que son iguales solo por nombre (que pueden o no ser útiles).
Tengo los siguientes tipos de datos algebraicos:
data Exp
= Con Int
| Var String
| Op Opkind Exp Exp
| Input
deriving (Show,Eq)
data Opkind
= Plus | Minus | Mult | Div | More | Equal
deriving (Show,Eq)
Que representan expresiones en un lenguaje de juguete simple.
Sin embargo, dado que obtengo Eq, Op Plus (Var "a") (Var "b)
no se considera igual a Op Plus (Var "b") (Var "a")
aunque me gustaría tratar a+b
como una expresión igual a b+a
.
¿Cómo cambio (==)
solo esas instancias, sin tener que especificar el comportamiento de (==)
para todas las demás instancias?
Puede lograr esto haciendo de Exp una instancia de Eq en lugar de derivar Eq:
instance Eq Exp where
(Con a) == (Con b) = a == b
(Var a) == (Var b) = a == b
(Op Plus a b) == (Op Plus c d) = (a == c && b == d) || (a == d && c == b)
Input == Input = True
_ == _ = False
Esto compararía Op Plus de la manera deseada, pero aún le faltan los otros casos para Op.
Editar:
La forma más fácil de implementar casos especiales para (==) en Op sin perder el derivado en Exp, me viene a la mente algo como esto:
data Exp
= Con Int
| Var String
| EOp Op
| Input
deriving (Show, Eq)
data Op = Op Opkind Exp Exp deriving (Show)
instance Eq Op where
(Op Plus e1 e2) == (Op Plus e3 e4) = (e1 == e3 && e2 == e4) || ( e1 == e4 && e2 == e3)
(Op kind1 e1 e2) == (Op kind2 e3 e4) = and [kind1 == kind2, e1 == e3, e2 == e4]