A general way to compare constructors of two members in Haskell

Given the two terms t1 t2 of some data type, is there a way to check if t1 and t2 start with the same constructor without doing any exhaustive case or pattern matching on the constructors? For example, if my type is either b, then I want

checkConst (Left x) (Left y) = True
checkConst (Right x) (Left y) = False
...

etc., without actually doing this pattern matching, and in a way that can be generalized to other types with about 10 constructors. Is there a good way to do this?

+4
source share
2 answers

You are probably looking for the generics functionality available in the module Data.Data. If you define a data type with a derived instance Data, for example:

{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
data Foo = Bar1 Int
         | Bar2 String String
         | Bar3 Double
         deriving (Data)

toConstr:

> toConstr (Bar1 1)
Bar1
> toConstr (Bar2 "hello" "there")
Bar2
>

Constr, , :

checkConst :: (Data g) => g -> g -> Bool
checkConst x y = toConstr x == toConstr y

:

> checkConst (Bar1 10) (Bar1 20)
True
> checkConst (Bar1 10) (Bar3 20)
False
>
+6

- , Eq. , Int, , .

checkConst x y = toInt x == toInt y
  where
    toInt (Left _)  = 1 :: Int
    toInt (Right _) = 2

Data Data.Data, toConstr Constr . Either , isRight x == isRight y, 10 .

+3

Source: https://habr.com/ru/post/1690942/


All Articles