add1 :: Int -> Code Q Int add1 x = [|| x + 1 ||]Template Haskell has no way of knowing what value x will take on at splice-time, so it requires the type of x to be an instance of Lift. A Lift instance must satisfy $(lift x) ≡ x and $$(liftTyped x) ≡ x for all x, where $(...) and $$(...) are Template Haskell splices. It is additionally expected that lift x ≡ unTypeCode (liftTyped x). Lift instances can be derived automatically by use of the -XDeriveLift GHC language extension:
{-# LANGUAGE DeriveLift #-} module Foo where import Language.Haskell.TH.Syntax data Bar a = Bar1 a (Bar a) | Bar2 String deriving LiftRepresentation-polymorphic since template-haskell-2.16.0.0.
>>> liftA (+1) [1, 2] [2,3]Or the Applicative instance for Maybe
>>> liftA (+1) (Just 3) Just 4
>>> liftA2 (,) (Just 3) (Just 5) Just (3,5)
>>> liftA2 (+) [1, 2, 3] [4, 5, 6] [5,6,7,6,7,8,7,8,9]
>>> liftM2 (+) [0,1] [0,2] [0,2,1,3]
>>> liftM2 (+) (Just 1) Nothing Nothing
>>> liftM2 (+) (+ 3) (* 2) 5 18
import Control.Monad.Trans.State -- from the "transformers" library printState :: Show s => StateT s IO () printState = do state <- get liftIO $ print stateHad we omitted liftIO, we would have ended up with this error:
• Couldn't match type ‘IO’ with ‘StateT s IO’ Expected type: StateT s IO () Actual type: IO ()The important part here is the mismatch between StateT s IO () and IO (). Luckily, we know of a function that takes an IO a and returns an (m a): liftIO, enabling us to run the program and see the expected results:
> evalStateT printState "hello" "hello" > evalStateT printState 3 3