sqlite-simple icon indicating copy to clipboard operation
sqlite-simple copied to clipboard

RowParser parameter has nominal role

Open Shimuuar opened this issue 2 years ago • 2 comments

This makes it impossible to use GND or deriving via to derive FromRow instances. This is rather annoying since there is no good reason for type variable to nominal.

Fixing this is possible but require some boilerplate

Shimuuar avatar May 23 '22 16:05 Shimuuar

To motivate the discussion and possible solution, do you have a code sample with error messages illustrating the problem to solve?

jchia avatar Jan 14 '24 11:01 jchia

As I said it makes impossible to use GND or deriving via which rely on coerce. As a simple example:

newtype Foo = Foo (Int,Int)
  deriving newtype FromRow

results in error:

    • Couldn't match type ‘(Int, Int)’ with ‘Foo’
        arising from the coercion of the method ‘fromRow’
          from type ‘RowParser (Int, Int)’ to type ‘RowParser Foo’
    • When deriving the instance for (FromRow Foo)

Reason for that is quite easy to see:

type role RowParser nominal

This in turn is caused by ReaderT:

type role ReaderT representational representational nominal

This could be fixed by unpacking ReaderT and using it only to derive instances. Something along the lines:

newtype RowParser a = RP { unRP :: ReaderT RowParseRO (StateT (Int, [Base.SQLData]) Ok) a }
   deriving ( Functor, Applicative, Alternative, Monad, MonadPlus )

newtype RowParser a = RP { unRP :: RowParseRO -> StateT (Int, [Base.SQLData]) Ok a }
   deriving ( Functor, Applicative, Alternative, Monad, MonadPlus ) via ReaderT RowParseRO (StateT (Int, [Base.SQLData]) Ok) a

Shimuuar avatar Jan 14 '24 17:01 Shimuuar