selda icon indicating copy to clipboard operation
selda copied to clipboard

not able to use GeneralizedNewtypeDeriving to derive SqlRow on newtype

Open cdepillabout opened this issue 5 years ago • 1 comments

I'm somewhat surprised that I am not able to use GeneralizedNewtypeDeriving to derive SqlRow on a newtype.

Here's a small example of the code that I'm trying to write:

{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE UndecidableInstances #-}

module Example where

import Database.Selda

data Foo = Foo
  { a :: Int
  , b :: Text
  }
  deriving stock (Eq, Generic, Show)
  deriving anyclass (SqlRow)

newtype Bar = Bar Foo
  deriving stock (Eq, Show)
  deriving newtype (Generic, SqlRow)

When trying to compile this, I get the error:

Example.hs:20:30: error:
    • Couldn't match type ‘Foo’ with ‘Bar’
        arising from the coercion of the method ‘nextResult’
          from type ‘selda-0.5.2.0:Database.Selda.SqlRow.ResultReader Foo’
            to type ‘selda-0.5.2.0:Database.Selda.SqlRow.ResultReader Bar’
    • When deriving the instance for (SqlRow Bar)
   |
20 |   deriving newtype (Generic, SqlRow)
   |             

After playing around with this for a little bit, I realized it is possible to write the SqlRow instance by hand, even though the ResultReader type is not exposed:

instance SqlRow Bar where
  nextResult = fmap Bar nextResult
  nestedCols _ = nestedCols (Proxy :: Proxy Foo)

Maybe this is just a non-issue. Hopefully this GitHub issue can help other users who stumble on it, but please feel free to just close it.

cdepillabout avatar Oct 14 '20 02:10 cdepillabout

I have the same issue with SqlType, using a simple newtype wrapper around Text.

(edit Ahh, I see: #13)

dhess avatar May 26 '21 14:05 dhess