Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalise kind of ForallT #54

Open
Icelandjack opened this issue May 4, 2017 · 4 comments
Open

Generalise kind of ForallT #54

Icelandjack opened this issue May 4, 2017 · 4 comments

Comments

@Icelandjack
Copy link
Contributor

Icelandjack commented May 4, 2017

Can the kind of ForallT be generalised

-- ForallT :: (k4 -> Constraint) -> ((k1 -> k2) -> k3 -> k4) -> Constraint
ForallT :: (k3 -> Constraint) -> (k1 -> k2 -> k3)

I need this to model PipeKit from Faster Coroutine Pipelines

class ForallT Monad pipe => PipeKit pipe where
  input :: pipe i o i
  output :: o -> pipe i o ()
  -- ...

Works by removing kind annotations

class    p (t a b)        => R p t a b
instance p (t a b)        => R p t a b

class    Forall (R p t a) => Q p t a
instance Forall (R p t a) => Q p t a

class    Forall (Q p t)   => ForallT p t
instance Forall (Q p t)   => ForallT p t

instT :: forall p t f a. ForallT p t :- p (t f a)
instT = Sub $
  case inst :: Forall (Q p t) :- Q p t f of { Sub Dict ->
  case inst :: Forall (R p t f) :- R p t f a of
    Sub Dict -> Dict }
@RyanGlScott
Copy link
Collaborator

It's certainly possible. This patch would suffice:

diff --git a/src/Data/Constraint/Forall.hs b/src/Data/Constraint/Forall.hs                
index 3932f29..f628993 100644                                                             
--- a/src/Data/Constraint/Forall.hs
+++ b/src/Data/Constraint/Forall.hs
@@ -139,11 +139,11 @@ class Forall (R p t a) => Q (p :: k3 -> Constraint) (t :: k1 -> k2 -> k3) (a ::
 instance Forall (R p t a) => Q p t a
 
 -- | A representation of the quantified constraint @forall f a. p (t f a)@.
-class Forall (Q p t) => ForallT (p :: k4 -> Constraint) (t :: (k1 -> k2) -> k3 -> k4)
+class Forall (Q p t) => ForallT (p :: k3 -> Constraint) (t :: k1 -> k2 -> k3)
 instance Forall (Q p t) => ForallT p t
 
 -- | Instantiate a quantified @'ForallT' p t@ constraint at types @f@ and @a@.
-instT :: forall (p :: k4 -> Constraint) (t :: (k1 -> k2) -> k3 -> k4) (f :: k1 -> k2) (a :: k3). ForallT p t :- p (t f a)
+instT :: forall (p :: k3 -> Constraint) (t :: k1 -> k2 -> k3) (f :: k1) (a :: k2). ForallT p t :- p (t f a)
 instT = Sub $
   case inst :: Forall (Q p t) :- Q p t f of { Sub Dict ->
   case inst :: Forall (R p t f) :- R p t f a of

The question is whether this would be desirable from a kind inference perspective. I'm guessing the current kind signature of ForallT was meant to be reminiscent of monad transformers, and generalizing the kind signature further makes this similarity less clear, especially if you used it incorrectly and saw the resulting error message.

But perhaps if you're using Data.Constraint.ForallT in the first place, you're already well aware of the risk of confusing error messages, and this wouldn't be so bad. :)

@Icelandjack
Copy link
Contributor Author

It could also be given a different name (the Forall suffix naming scheme remains a mystery to me)

@oerjan
Copy link
Contributor

oerjan commented May 6, 2017

I initially implemented the new system's ForallT precisely as you suggest, but restricted it again because it broke one of the packages on Hackage. See this pull request.

@sjoerdvisscher
Copy link
Collaborator

I'm no longer using ForallT, it didn't really work after all: sjoerdvisscher/free-functors@643cd1d

But of course it might break something else.

I guess Forall2 would be a sensible name for this one? With ForallT being the same with an extra kind annotation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants