Retrieving an Identifier Using GHC.Generics

How to extract an identifier (in this case an integer) from a structure using GHC.Generics?

I have a type Id:

newtype Id = Id { _id :: Int }

and many types that use this type:

data VarId = VarId Name Id SortId
data FuncId = FuncId Name Id [SortId] SortId
data SortId = Name Id
-- ... and 20 more of these things

In addition, there are other types that carry the above types, for example, identifiers:

data Identifier = IdVar VarId
                | IdFunc FuncId
                | IdSort SortId
                -- ... and 20 more of these things

Now I need to extract the field _idfrom any of these types containing the value Id. We currently have tons of templates for this, and I want to abandon it with generics.

At first I thought of a class definition:

class Identifiable e where
    getId :: e -> Id

    default getId :: (Generic e, GIdentifiable (Rep e)) => e -> Id
    getId = gGetId . from

class GIdentifiable f where
    gGetId :: f e -> Id

, Identifiable , Id ( , , FuncId ) Id, ). , GIdentifiable . - :

instance (GIdentifiable a) => GIdentifiable (a :*: b) where
    gGetId (a :*: _) = gGetId a

instance {-# OVERLAPS #-} (GIdentifiable b) => GIdentifiable (a :*: b) where
gGetId (_ :*: b) = gGetId b

, .

Identifiable, getId :: e -> Maybe Id, , , Id.

?

+1

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


All Articles