@@ -18,7 +18,7 @@ import Data.Aeson ((.:), (.=), withObject, object)
18
18
import Data.Aeson.Types (Parser , Value )
19
19
import Data.Hashable (Hashable (.. ))
20
20
import Data.Text (Text )
21
- import Data.Typeable (typeOf , typeRepTyCon , typeRep , Typeable , cast )
21
+ import Data.Typeable (Typeable , cast , splitTyConApp , typeOf , typeRep )
22
22
#if !MIN_VERSION_base(4, 11, 0)
23
23
import Data.Semigroup
24
24
#endif
@@ -165,12 +165,15 @@ instance DatabasePredicate TableHasIndex where
165
165
-- | Match a given item's type against a type-level application with the given
166
166
-- type constructor. Applies the given function and returns 'Just' its result on match,
167
167
-- 'Nothing' otherwise.
168
+ -- Unlike 'cast', this function does not require @a@ type to be instance of 'Typeable'.
168
169
withTyCon
169
170
:: forall (con :: * -> * ) (item :: * ) r .
170
171
(Typeable con , Typeable item )
171
172
=> (forall a . con a -> r ) -> item -> Maybe r
172
173
withTyCon f x = do
173
- guard (typeRepTyCon (typeRep (Proxy @ item )) == typeRepTyCon (typeOf x))
174
+ (itemTyCon, itemTyArgs@ (_ : _)) <- pure $ splitTyConApp (typeOf x)
175
+ (conTyCon, conTyArgs) <- pure $ splitTyConApp (typeRep (Proxy @ con ))
176
+ guard (itemTyCon == conTyCon && init itemTyArgs == conTyArgs)
174
177
return (f $ unsafeCoerce x)
175
178
176
179
-- | Convert gathered indices into checks.
0 commit comments