Type synonym involing quantified constraint?

I'm working on Conal's ConCat code, and keep putting quantified constraints like this in instance constraints: (okk ~ Ok k, forall x y. (okk x, okk y) => okk (Prod k x y)) (The okk ~ Ok k is necessary because Ok is an associated type.) Is there any way to define a type synonym for this? Like type OkProd k = (okk ~ Ok k, forall x y. (okk x, okk y) => okk (Prod k x y)) ghc (8.10.4) complains about an impredicative type. Help would be much appreciated! -- Regards, Mike

This looks like a bug, which I've now filed: https://gitlab.haskell.org/ghc/ghc/-/issues/20318 The workaround is to enable ImpredicativeTypes. Sadly, ImpredicativeTypes is really a bug in GHC 8.10, fixed to work properly in GHC 9.2. So if I were doing this, I would define the offending synonym in a module all by itself so that the scope of ImpredicativeTypes is as small as possible. Richard
On Aug 31, 2021, at 11:45 AM, Michael Sperber
wrote: I'm working on Conal's ConCat code, and keep putting quantified constraints like this in instance constraints:
(okk ~ Ok k, forall x y. (okk x, okk y) => okk (Prod k x y))
(The okk ~ Ok k is necessary because Ok is an associated type.)
Is there any way to define a type synonym for this? Like
type OkProd k = (okk ~ Ok k, forall x y. (okk x, okk y) => okk (Prod k x y))
ghc (8.10.4) complains about an impredicative type.
Help would be much appreciated!
-- Regards, Mike
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

Thanks for looking at this!
On Tue, Aug 31 2021, Richard Eisenberg
This looks like a bug, which I've now filed: https://gitlab.haskell.org/ghc/ghc/-/issues/20318
The workaround is to enable ImpredicativeTypes.
So I did that and then tried defining it like this: type OkProd'' :: (Type -> Type -> Type) -> Constraint type OkProd'' k = forall okk. (okk ~ Ok k, forall x y. (okk x, okk y) => okk (Prod k x y)) ... but get: src/ConCat/Category.hs:228:1: error: • You can't specify an instance for a tuple constraint • In the quantified constraint ‘forall (okk :: * -> Constraint). (okk ~ Ok k, forall x y. (okk x, okk y) => okk (Prod k x y))’ In the type synonym declaration for ‘OkProd''’ (What does this message even mean? :-) ) -- Regards, Mike

Hm. Interesting. You are trying to work around the fact that okk is not in scope. The problem is that GHC does not currently allow you to specify a tuple as the head of a quantified constraint. The thinking is that (forall x. premise => (conclusion1, conclusion2)) can always be refactored into (forall x. premise => conclusion1, forall x. premise => conclusion2). In your case, the refactoring is not so simple, but it can be done. Try
type OkProd k = forall (okk :: Type -> Constraint) x y. (okk ~ Ok k, okk x, okk y) => okk (Prod k x y)
Does that work for you? If not, it may be helpful to see a function that uses the OkProd constraint somewhere. I hope this helps! Richard
On Sep 1, 2021, at 6:47 AM, Michael Sperber
wrote: Thanks for looking at this!
On Tue, Aug 31 2021, Richard Eisenberg
wrote: This looks like a bug, which I've now filed: https://gitlab.haskell.org/ghc/ghc/-/issues/20318
The workaround is to enable ImpredicativeTypes.
So I did that and then tried defining it like this:
type OkProd'' :: (Type -> Type -> Type) -> Constraint type OkProd'' k = forall okk. (okk ~ Ok k, forall x y. (okk x, okk y) => okk (Prod k x y))
... but get:
src/ConCat/Category.hs:228:1: error: • You can't specify an instance for a tuple constraint • In the quantified constraint ‘forall (okk :: * -> Constraint). (okk ~ Ok k, forall x y. (okk x, okk y) => okk (Prod k x y))’ In the type synonym declaration for ‘OkProd''’
(What does this message even mean? :-) )
-- Regards, Mike _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

On Thu, Sep 02 2021, Richard Eisenberg
Hm. Interesting. You are trying to work around the fact that okk is not in scope.
The problem is that GHC does not currently allow you to specify a tuple as the head of a quantified constraint. The thinking is that (forall x. premise => (conclusion1, conclusion2)) can always be refactored into (forall x. premise => conclusion1, forall x. premise => conclusion2).
In your case, the refactoring is not so simple, but it can be done. Try
type OkProd k = forall (okk :: Type -> Constraint) x y. (okk ~ Ok k, okk x, okk y) => okk (Prod k x y)
Does that work for you? If not, it may be helpful to see a function that uses the OkProd constraint somewhere.
Unfortunately, no. I've attached a self-contained example. It works as-is. But when I replace, in the ProductCat (Same k) instance, OkProdInstance (CPP FTW) by OkProdInstance' (the definition you suggested), I get: classes/src/ConCat/Constraints.hs:55:10: error: • Could not deduce: Ok k ~ Ok' (Same k) arising from the superclasses of an instance declaration from the context: (Ok' (Same k) x, Ok' (Same k) y) bound by a quantified context at classes/src/ConCat/Constraints.hs:1:1 • In the instance declaration for ‘ProductCat (Same k)’ | 55 | instance (ProductCat k, OkProdInstance'(k)) => ProductCat (Same k) where | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Regards, Mike {-# LANGUAGE CPP #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE UndecidableSuperClasses #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE QuantifiedConstraints #-} {-# LANGUAGE StandaloneKindSignatures #-} module ConCat.Constraints where import Prelude hiding (id,(.)) import GHC.Types (Constraint, Type) class Yes1 a instance Yes1 a class Category k where type Ok k :: Type -> Constraint type Ok k = Yes1 id :: Ok k a => a `k` a infixr 9 . (.) :: forall b c a. (Ok k a, Ok k b, Ok k c) => (b `k` c) -> (a `k` b) -> (a `k` c) class Ok k a => Ok' k a instance Ok k a => Ok' k a type OkProd :: (Type -> Type -> Type) -> Constraint type OkProd k = forall x y. (Ok' k x, Ok' k y) => Ok' k (x, y) #define OkProdInstance(k) okk ~ Ok (k), forall x y. (okk x, okk y) => okk (x, y) type OkProdInstance' :: (Type -> Type -> Type) -> Constraint type OkProdInstance' k = forall (okk :: Type -> Constraint) x y. (okk ~ Ok k, okk x, okk y) => okk (x, y) class (Category k, OkProd k) => ProductCat k where exl :: (Ok k a, Ok k b) => (a, b) `k` a exr :: (Ok k a, Ok k b) => (a, b) `k` b dup :: Ok k a => a `k` (a, a) data Same k a b = Same (a `k` b) instance Category k => Category (Same k) where type Ok (Same k) = Ok k id = Same id Same g . Same f = Same (g . f) instance (ProductCat k, OkProdInstance'(k)) => ProductCat (Same k) where exl = Same exl exr = Same exr dup = Same dup
participants (2)
-
Michael Sperber
-
Richard Eisenberg