From cf735db883b2ff83e61f9848a39f1066d3288a43 Mon Sep 17 00:00:00 2001
From: Andrei Borzenkov <andreyborzenkov2002@gmail.com>
Date: Mon, 3 Jul 2023 16:45:57 +0400
Subject: [PATCH] Add Note about why we need forall in Code to be on the right

---
 .../Language/Haskell/TH/Syntax.hs             | 20 +++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
index 42d01ffd581c..b3b730ee83c9 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
@@ -380,8 +380,7 @@ The splice will evaluate to (MkAge 3) and you can't add that to
 -- Code constructor
 #if __GLASGOW_HASKELL__ >= 909
 type Code :: (Kind.Type -> Kind.Type) -> forall r. TYPE r -> Kind.Type
-  -- The nested `forall` makes it possible to assign the arity of 0 to
-  --   type CodeQ = Code Q
+  -- See Note [Foralls to the right in Code]
 #else
 type Code :: (Kind.Type -> Kind.Type) -> TYPE r -> Kind.Type
 #endif
@@ -424,6 +423,23 @@ newtype Code m a = Code
 --       In the Template Haskell splice $$([|| "foo" ||])
 
 
+{- Note [Foralls to the right in Code]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Code has the following type signature:
+   type Code :: (Kind.Type -> Kind.Type) -> forall r. TYPE r -> Kind.Type
+
+This allows us to write
+   data T (f :: forall r . (TYPE r) -> Type) = MkT (f Int) (f Int#)
+
+   tcodeq :: T (Code Q)
+   tcodeq = MkT [||5||] [||5#||]
+
+If we used the slightly more straightforward signature
+   type Code :: foral r. (Kind.Type -> Kind.Type) -> TYPE r -> Kind.Type
+
+then the example above would become ill-typed.  (See #23592 for some discussion.)
+-}
+
 -- | Unsafely convert an untyped code representation into a typed code
 -- representation.
 unsafeCodeCoerce :: forall (r :: RuntimeRep) (a :: TYPE r) m .
-- 
GitLab