circuithub / rel8

Hey! Hey! Can u rel8?
https://rel8.readthedocs.io
Other
150 stars 38 forks source link

Using `DBEnum` with a newtype wrapper #294

Closed elldritch closed 7 months ago

elldritch commented 7 months ago

Is it possible to use a newtype as an enum?

My use case here is that I'm importing an enum from another not-database-related module, so I'd rather define DBType, DBEq, etc. instances on a newtype wrapper than in the original module itself. So my program looks something like:

-- module A

data UnderlyingType = SumA | SumB | SumC

-- module B

newtype NewtypeWrapperOfUnderlyingType = Wrapper UnderlyingType
  deriving (Eq, Show, Generic, DBType, DBEq, DBOrd)

instance DBEnum NewtypeWrapperOfUnderlyingType where
  -- ...

I would like to represent the column using an enum in Postgres, but when I try to define an instance DBEnum NewtypeWrapperOfUnderlyingType, the compiler tells me:

No instance for (rel8-1.4.1.0:Rel8.Type.Enum.GEnumable
                     (GHC.Generics.M1
                        GHC.Generics.C
                        ('GHC.Generics.MetaCons
                           "NewtypeWrapperOfUnderlyingType" 'GHC.Generics.PrefixI 'False)
                        (GHC.Generics.S1
                           ('GHC.Generics.MetaSel
                              'Nothing
                              'GHC.Generics.NoSourceUnpackedness
                              'GHC.Generics.NoSourceStrictness
                              'GHC.Generics.DecidedLazy)
                           (GHC.Generics.Rec0 UnderlyingType))))
    arising from the superclasses of an instance declaration
• In the instance declaration for
    ‘DBEnum NewtypeWrapperOfUnderlyingType’

Am I holding the library wrong, or is this unsupported?

I've also tried defining the DBEnum instance directly on UnderlyingType and then using deriving newtype, but that gives me the same error with the addition of:

Possible fix:
    use a standalone 'deriving instance' declaration,
      so you can specify the instance context yourself
• When deriving the instance for (DBEnum AlpinePackageArchitecture)

I don't fully understand the suggestion - I tried using standalone deriving and deriving via, but I was basically grasping at straws with those.

elldritch commented 7 months ago

I read more carefully and it looks like I can just set typeName on TypeInformation, and Enum is just a convenience wrapper over that. Nevermind, PEBCAK.