开发者

Overriding (==) in Haskell

开发者 https://www.devze.com 2023-03-03 22:39 出处:网络
I have the following algebraic data types: data Exp = Con Int Var String Op开发者_JAVA技巧 Opkind Exp Exp

I have the following algebraic data types:

data Exp
  = Con Int
  | Var String
  | Op开发者_JAVA技巧 Opkind Exp Exp
  | Input
  deriving (Show,Eq)

data Opkind
  = Plus | Minus | Mult | Div | More | Equal
  deriving (Show,Eq)

That represent expressions in a simple toy language.

However, because I derive Eq, Op Plus (Var "a") (Var "b) is not considered equal to Op Plus (Var "b") (Var "a") even though I would like to treat a+b as an equal expression to b+a.

How do I change (==) for just those instances, without having to specify the behaviour of (==) for all the other instances?


You can achieve this by making Exp an instance of Eq instead of deriving 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

This would compare Op Plus in the way wanted, but is still missing the other cases for Op.

Edit:

The easiest way to implement special cases for (==) on Op without losing the derive on Exp, that comes to my mind would be something like this:

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]


If you want custom behavior for Op, but regular behavior for all other variants of your datatype, you'll need to break out Op into its own type.

For example:

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

Let's you define all expressions structurally equal, except for applications of functions to arguments, which are equal by name only (which may or may not be useful).

0

精彩评论

暂无评论...
验证码 换一张
取 消