on master help sign in
Fix Rel8able to work with polymorphic types (#113)

Currently, a declaration such as: ```haskell newtype IdRecord a f = IdRecord { recordId :: Column f a } deriving Generic instance DBType a => Rel8able (IdRecord a) ``` Will fail, producing the error: ``` • Could not deduce (rel8-1.0.0.1:Rel8.Generic.Rel8able.Serialize (a Data.Type.Equality.== Identity a) (Expr a) a) arising from a use of ‘rel8-1.0.0.1:Rel8.Generic.Rel8able.$dmgfromColumns’ from the context: DBType a bound by the instance declaration at lib/CircuitHub/Model/Types.hs:231:10-42 ``` The stuck `==` type family gets in the way, even though we can clearly see that this is `False`. This commit fixes this error by introducing a variation of `==` that anticipates this case, adding an explicit pattern. With this new definition of `==`, things work as expected.

commit0532a6193c97c673583aca93fd4e951b5d7f9fcf authorOllie Charles <oliver.charles@circuithub.com> dateThu 8 Jul 2021, 15:34 (5 years ago) parent032242f
2 files changed+25−1
src/Rel8/Generic/Rel8able.hs+17−1 tests/Rel8/Generic/Rel8able/Test.hs+8
src/Rel8/Generic/Rel8able.hs+17−1
@@ -6,6 +6,7 @@
66{-# language FlexibleInstances #-}
77{-# language LambdaCase #-}
88{-# language MultiParamTypeClasses #-}
9+{-# language PolyKinds #-}
910{-# language QuantifiedConstraints #-}
1011{-# language ScopedTypeVariables #-}
1112{-# language StandaloneKindSignatures #-}
@@ -25,8 +26,9 @@ module Rel8.Generic.Rel8able
2526where
2627
2728-- base
29+import Data.Functor.Identity ( Identity )
2830import Data.Kind ( Constraint, Type )
29−import Data.Type.Equality ( type (==) )
31+import Data.Type.Bool ( type (&&) )
3032import GHC.Generics ( Generic, Rep, from, to )
3133import Prelude
3234
@@ -58,6 +60,20 @@ type KRel8able :: Type
5860type KRel8able = K.Rel8able
5961
6062
63+-- This is almost 'Data.Type.Equality.==', but we add an extra case.
64+type (==) :: k -> k -> Bool
65+type family a == b where
66+ -- This extra case is needed to solve the equation "a == Identity a",
67+ -- which occurs when we have polymorphic Rel8ables
68+ -- (e.g., newtype T a f = T { x :: Column f a })
69+ a == Identity a = 'False
70+
71+ -- These cases are exactly the same as those in 'Data.Type.Equality.==.
72+ f a == g b = f == g && a == b
73+ a == a = 'True
74+ _ == _ = 'False
75+
76+
6177type Serialize :: Bool -> Type -> Type -> Constraint
6278class transposition ~ (a == Transpose Result expr) =>
6379 Serialize transposition expr a
tests/Rel8/Generic/Rel8able/Test.hs+8
@@ -169,3 +169,11 @@ data NestedTableTestB f = NestedTableTestB
169169 }
170170 deriving stock Generic
171171 deriving anyclass Rel8able
172+
173+
174+
175+newtype IdRecord a f = IdRecord { recordId :: Column f a }
176+ deriving stock Generic
177+
178+
179+instance DBType a => Rel8able (IdRecord a)