How to convince GHC that this pattern synonym is complete?

Viewed 108

I'm using GHC 9.0.1. I have this typeclass:

{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}

import Data.Kind

type Has :: ((Type -> Type) -> Type) -> (Type -> Type) -> Type -> Constraint
class Has r_ m env | env -> m where
  dep :: env -> r_ m

And this (admittedly weird) rank-2 function:

makeCaller :: forall env m . env -> forall r_ x. Has r_ m env => (r_ m -> x) -> x
makeCaller env = \f -> f (dep env)

which I use as a view pattern. I want to hide the use of the view pattern behind this pattern synonym:

pattern Call :: forall env m . (forall r_ x. Has r_ m env => (r_ m -> x) -> x) -> env
pattern Call env <- (makeCaller -> env)

Which actually works fine, except for one thing: in monadic contexts, it requires a MonadFail constraint from the monad. I would like to remove the need for MonadFail by marking the pattern synonym as COMPLETE:

{-# COMPLETE Call #-}

Alas, it doesn't work:

* A type signature must be provided for a set of polymorphic pattern synonyms.
* In {-# COMPLETE Call #-}

I don't know what signature should be given in the pragma. Putting the whole forall env m . (forall r_ x. Has r_ m env => (r_ m -> x) -> x) -> env gives a parse error.

Is there a way to mark the pattern synonym as COMPLETE?

0 Answers
Related