lpsmith / postgresql-simple

Mid-level client library for accessing PostgreSQL from Haskell
Other
206 stars 71 forks source link

`ToRow` deriving works in ghci but not with GHC #194

Closed ivan-m closed 7 years ago

ivan-m commented 8 years ago

I have a module that - stripped out of unnecessary fluff (that I tested was indeed irrelevant by commenting out) contains the following:

{-# LANGUAGE DeriveAnyClass, DeriveGeneric #-}

import Database.PostgreSQL.Simple
import GHC.Generics

data Claim = Claim { claimNumber :: String
                   , repairerRef :: String
                   , vin         :: Maybe String
                   , rego        :: Maybe String
                   }
  deriving (Eq, Ord, Show, Read, Generic, ToRow)

If I load this up in cabal repl then there's no problems; however, if I try to cabal build it then I get the following error message:

src/Main.hs:86:43: error:
    • No instance for (ToRow (Maybe String))
        arising from the third field of ‘Claim’ (type ‘Maybe String’)
      Possible fix:
        use a standalone 'deriving instance' declaration,
          so you can specify the instance context yourself
    • When deriving the instance for (ToRow Claim)

despite the fact that I can do this in the repl:

λ> import Database.PostgreSQL.Simple.ToRow
λ> toRow (Claim "claim" "repairer" (Just "vin") Nothing)
[Escape "claim",Escape "repairer",Escape "vin",Plain "null"]
lpsmith commented 8 years ago

I'll have to dig into this a bit, but there would seem to be an issue with GHC and/or GHCi. There may well also be an issue with postgresql-simple.

Before I dig in, it may be worth pointing out that there's almost but not quite a ToRow instance for Maybe String: there is a ToRow instance for lists, and ToRow instances for some Maybe types, though not for Maybe [...].

Even so, the issue should intuitively be a FromField error. I'll have to dig in to it more at some point.

lpsmith commented 8 years ago

Ok, playing around with your example a bit with GHCi 7.10.2, as-is your example produces the same type error. However, using the default instance definitions by writing instance ToRow Claim without deriving (ToRow) works just fine.

Looking at the documentation for DeriveAnyClass, I don't understand how this would be "correct" behavior on the part of GHC, because the documentation claims that those two alternative declarations should be equivalent. But clearly, in actuality they are not.

ivan-m commented 7 years ago

This has nothing to do with the Maybe as it applies even if I remove it.

I've reported this to the GHC Trac.