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