yesodweb / persistent

Persistence interface for Haskell allowing multiple storage methods.
MIT License
465 stars 294 forks source link

Deriving Typeclasses with Arguments #1405

Open Burtannia opened 2 years ago

Burtannia commented 2 years ago

Version: 2.14.0.0 Stack LTS: 19.5

Take the following typeclass:

class Pointless a b where
    lol :: a -> b -> ()
    lol = const $ const ()

This could be derived as follows:

data Something = Something
    { a :: Int
    , b :: Int
    } deriving (Pointless Int)

However the following fails as a persistent template:

Person
    name String
    age Int
    deriving Show (Pointless Int)

The error given is Illegal type constructor or class name: ‘Pointless Int’.

And the deriving statements appear to be expanded to:

    deriving stock Show
    deriving anyclass Pointless Int

I assume it's due to the omission of the brackets in the generated code? Is there a way I can get persistent to keep them, is this a bug or just not something that is supported?

parsonsmatt commented 2 years ago

Huh, yeah, that seems like it should be supportable.

As a work-around, you can do a standalone deriving instance after the deriving call.

module Person where

mkPersist sqlSettings [persistLowerCase|
Person
  name String
  age Int
  deriving Show
|]

deriving anyclass instance Pointless Int Person

Or even just (if it's all just default annotations)

instance Pointless Int Person