5

Suppose, I have the following code

data F a where
  F :: Typeable a => F a

asType :: forall b a. Typeable b => F a -> Maybe (a :~: b, F b)
asType e@F{} = case eqT @b @a of
  Just Refl -> Just (Refl, e)
  Nothing -> Nothing

pattern AsType :: forall a b. Typeable a => (a ~ b) => F a -> F b
pattern AsType e <- (asType @a -> Just (Refl, e))

pattern AsInt :: Typeable b' => (Int ~ b') => F Int -> F b'
pattern AsInt e <- AsType e -- doesn't compile

If I could explicitly instantiate the type parameter a in AsType with Int and the type parameter b with b' it would probably work.

I tried to give AsType it an explicit type signature ((AsType :: …) e) and it's a parsing error. I tried to use type applications — to no avail as well.

How can I make it work, if it's possible? If not, why?

(I can implement AsInt through a pattern view with asType, but that it isn't interesting and also more verbose)

grepcake
  • 3,960
  • 3
  • 16
  • 26
  • Maybe this is a syntax that I'm just unaware of, but shouldn't the type equality constraints be grouped together with the `Typeable` constraints? I didn't know you can have `=>` twice in the same type. When I change it to `(Typeable b', Int ~ b')` it compiles, and also when I remove the type equality constraint it compiles. – 4castle Jul 26 '22 at 10:12
  • 1
    @4castle, the syntax has special meaning for pattern synonyms. Basically, the second set of constraints is what is proven, if the match is successful. If you move it to the first set, it is what is required for the match to be successful. See https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/exts/pattern_synonyms.html#typing-of-pattern-synonyms – grepcake Jul 26 '22 at 10:37
  • Relevant maybe, https://mpickering.github.io/posts/2016-06-18-why-no-refinement.html and https://gitlab.haskell.org/ghc/ghc/-/issues/21757 – Iceland_jack Jul 26 '22 at 23:46
  • @Iceland_jack I might misunderstand something, but I think the post is not exactly right. It says «For type class constraints, the dictionaries must be bound when the constructor is used to construct values». However, `eqT` shows that the dictionary can be bound at any other time, given `Typeable`. Also, these patterns do work, when implemented via `asType`, so that also seems like a contradiction to the post. Or maybe I misinterpreted it. – grepcake Jul 27 '22 at 08:41
  • Another quote «But, the set of provided constraints must be exactly those constraints which the underlying constructor provides». However, additional provided constraints can be proven from the set of required constraints and the constraints provided by the constructor – grepcake Jul 27 '22 at 08:49

0 Answers0