Add 'Lift' instances for 'NonEmpty' and 'Void'
authorAlec Theriault <alec.theriault@gmail.com>
Fri, 30 Nov 2018 14:18:10 +0000 (09:18 -0500)
committerRyan Scott <ryan.gl.scott@gmail.com>
Fri, 30 Nov 2018 14:46:42 +0000 (09:46 -0500)
Summary:
Since 'NonEmpty' and 'Void' are now part of 'base', it makes
sense that we put 'Lift' instances for them in 'template-haskell'.
Not doing so is going to force users to define their own (possibly
colliding) orphan instances downstream.

Test Plan: ./validate

Reviewers: goldfire, bgamari, RyanGlScott

Reviewed By: RyanGlScott

Subscribers: RyanGlScott, rwbarton, carter

GHC Trac Issues: #15961

Differential Revision: https://phabricator.haskell.org/D5391

libraries/template-haskell/Language/Haskell/TH/Syntax.hs
libraries/template-haskell/changelog.md
testsuite/tests/quotes/TH_localname.stderr
testsuite/tests/th/TH_Lift.hs

index b75a048..ef44a5c 100644 (file)
@@ -34,6 +34,8 @@ import Control.Monad.IO.Class (MonadIO (..))
 import System.IO        ( hPutStrLn, stderr )
 import Data.Char        ( isAlpha, isAlphaNum, isUpper )
 import Data.Int
+import Data.List.NonEmpty ( NonEmpty(..) )
+import Data.Void        ( Void, absurd )
 import Data.Word
 import Data.Ratio
 import GHC.Generics     ( Generic )
@@ -701,6 +703,17 @@ liftString :: String -> Q Exp
 -- Used in TcExpr to short-circuit the lifting for strings
 liftString s = return (LitE (StringL s))
 
+-- | @since 2.15.0.0
+instance Lift a => Lift (NonEmpty a) where
+  lift (x :| xs) = do
+    x' <- lift x
+    xs' <- lift xs
+    return (InfixE (Just x') (ConE nonemptyName) (Just xs'))
+
+-- | @since 2.15.0.0
+instance Lift Void where
+  lift = pure . absurd
+
 instance Lift () where
   lift () = return (ConE (tupleDataName 0))
 
@@ -752,6 +765,9 @@ leftName, rightName :: Name
 leftName  = mkNameG DataName "base" "Data.Either" "Left"
 rightName = mkNameG DataName "base" "Data.Either" "Right"
 
+nonemptyName :: Name
+nonemptyName = mkNameG DataName "base" "GHC.Base" ":|"
+
 -----------------------------------------------------
 --
 --              Generic Lift implementations
index de8b96f..5dca983 100644 (file)
@@ -12,6 +12,8 @@
     `Maybe [TyVarBndrQ]` argument. Non-API-breaking versions of these
     functions can be found in `Language.Haskell.TH.Lib`.
 
+  * Add `Lift` instances for `NonEmpty` and `Void`
+
 ## 2.14.0.0 *TBA*
 
   * Introduce an `addForeignFilePath` function, as well as a corresponding
index 41eb988..df38597 100644 (file)
@@ -19,7 +19,7 @@ TH_localname.hs:3:11: error:
                  Language.Haskell.TH.Syntax.Lift (Maybe a)
           -- Defined in ‘Language.Haskell.TH.Syntax’
         ...plus 14 others
-        ...plus 10 instances involving out-of-scope types
+        ...plus 12 instances involving out-of-scope types
         (use -fprint-potential-instances to see them all)
     • In the expression: Language.Haskell.TH.Syntax.lift y
       In the expression:
index eff0f1b..87bd47b 100644 (file)
@@ -9,6 +9,7 @@ import Data.Ratio
 import Data.Word
 import Data.Int
 import Numeric.Natural
+import Data.List.NonEmpty
 
 a :: Integer
 a = $( (\x -> [| x |]) (5 :: Integer) )
@@ -76,4 +77,6 @@ n = $( (\x -> [| x |]) () )
 o :: (Bool, Char, Int)
 o = $( (\x -> [| x |]) (True, 'x', 4 :: Int) )
 
+p :: NonEmpty Char
+p = $( (\x -> [| x |])  ('a' :| "bcde") )