yourself learn functions haskell types typeclass algebraic-data-types

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]