{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} #if __GLASGOW_HASKELL__ >= 706 {-# LANGUAGE DataKinds #-} #endif #if !MIN_VERSION_containers(0,5,8) {-# OPTIONS_GHC -fno-warn-orphans #-} #endif {-| Module: Types Copyright: (C) 2015-2017 Ryan Scott License: BSD-style (see the file LICENSE) Maintainer: Ryan Scott Data types for testing `lift-generics`' capabilities. -} module Types ( PureQ, runPureQ , Unit(..) , Product(..) , Sum(..) , Const(..) , Ap(..) , p, s, u, c, z, w #if MIN_VERSION_base(4,5,0) , Unit'(..) , Product'(..) , Sum'(..) , Const'(..) , Ap'(..) , p', s', u', c', z' #endif ) where import Data.Tree (Tree (..)) #if MIN_VERSION_base(4,5,0) import Data.Typeable (Typeable) #endif import Control.Monad.State import Generics.Deriving.TH (deriveAll) import GHC.Exts import Language.Haskell.TH.Lift.Generics ( genericLiftWithPkg #if MIN_VERSION_base(4,5,0) , genericLift #endif #if MIN_VERSION_template_haskell(2,16,0) , genericLiftTypedCompatWithPkg , genericLiftTypedCompat #endif ) import Language.Haskell.TH.Syntax hiding (newName) import Language.Haskell.TH.Syntax.Compat import Prelude () import Prelude.Compat newtype PureQ a = MkPureQ (State Uniq a) deriving (Functor, Applicative, Monad, MonadState Uniq) runPureQ :: PureQ a -> a runPureQ m = case m of MkPureQ m' -> evalState m' 0 instance Quote PureQ where newName s = state $ \i -> (mkNameU s i, i + 1) #if !MIN_VERSION_containers(0,5,8) $(deriveAll ''Tree) #endif data Unit = Unit deriving (Eq, Ord, Show) $(deriveAll ''Unit) data Product a b c d = Product a b c d deriving (Eq, Ord, Show) $(deriveAll ''Product) data Sum a b = Inl a | Inr b deriving (Eq, Ord, Show) $(deriveAll ''Sum) newtype Const a b = Const a deriving (Eq, Ord, Show) $(deriveAll ''Const) newtype Ap f a = Ap (f a) deriving (Eq, Ord, Show) $(deriveAll ''Ap) data Unboxed a = Unboxed a #if MIN_VERSION_template_haskell(2,11,0) Char# #endif Double# Float# Int# Word# deriving (Eq, Ord, Show) $(deriveAll ''Unboxed) p :: Product Char Int Bool String p = Product 'a' 1 True "b" s :: Sum Char Int s = Inl 'c' u :: Unboxed Int u = Unboxed 1 #if MIN_VERSION_template_haskell(2,11,0) '1'# #endif 1.0## 1.0# 1# 1## c :: Const Int a c = Const 1 z :: Ap Maybe Int z = Ap (Just 3) w :: Tree Int w = Node 3 [Node 4 [], Node 5 []] #if MIN_VERSION_base(4,5,0) -- The types below are essentially the same as the ones above. However, we -- give them genericLift-based instances rather than genericLiftWithPkg ones, -- to ensure that the former work too. data Unit' = Unit' deriving (Eq, Ord, Show, Typeable) $(deriveAll ''Unit') data Product' a b c d = Product' a b c d deriving (Eq, Ord, Show, Typeable) $(deriveAll ''Product') data Sum' a b = Inl' a | Inr' b deriving (Eq, Ord, Show, Typeable) $(deriveAll ''Sum') newtype Const' a b = Const' a deriving (Eq, Ord, Show, Typeable) $(deriveAll ''Const') newtype Ap' f a = Ap' (f a) deriving (Eq, Ord, Show) #if __GLASGOW_HASKELL__ >= 708 deriving instance Typeable Ap' #endif $(deriveAll ''Ap') data Unboxed' a = Unboxed' a # if MIN_VERSION_template_haskell(2,11,0) Char# # endif Double# Float# Int# Word# deriving (Eq, Ord, Show, Typeable) $(deriveAll ''Unboxed') p' :: Product' Char Int Bool String p' = Product' 'a' 1 True "b" s' :: Sum Char Int s' = Inl 'c' u' :: Unboxed' Int u' = Unboxed' 1 # if MIN_VERSION_template_haskell(2,11,0) '1'# # endif 1.0## 1.0# 1# 1## c' :: Const' Int a c' = Const' 1 z' :: Ap' Maybe Int z' = Ap' (Just 3) #endif pkgKey :: String pkgKey = "main" instance Lift Unit where lift = genericLiftWithPkg pkgKey #if MIN_VERSION_template_haskell(2,16,0) liftTyped = genericLiftTypedCompatWithPkg pkgKey #endif instance (Lift a, Lift b, Lift c, Lift d) => Lift (Product a b c d) where lift = genericLiftWithPkg pkgKey #if MIN_VERSION_template_haskell(2,16,0) liftTyped = genericLiftTypedCompatWithPkg pkgKey #endif instance (Lift a, Lift b) => Lift (Sum a b) where lift = genericLiftWithPkg pkgKey #if MIN_VERSION_template_haskell(2,16,0) liftTyped = genericLiftTypedCompatWithPkg pkgKey #endif instance Lift a => Lift (Unboxed a) where lift = genericLiftWithPkg pkgKey #if MIN_VERSION_template_haskell(2,16,0) liftTyped = genericLiftTypedCompatWithPkg pkgKey #endif instance Lift a => Lift (Const a b) where lift = genericLiftWithPkg pkgKey #if MIN_VERSION_template_haskell(2,16,0) liftTyped = genericLiftTypedCompatWithPkg pkgKey #endif instance Lift (f a) => Lift (Ap f a) where lift = genericLiftWithPkg pkgKey #if MIN_VERSION_template_haskell(2,16,0) liftTyped = genericLiftTypedCompatWithPkg pkgKey #endif #if MIN_VERSION_base(4,5,0) instance Lift Unit' where lift = genericLift # if MIN_VERSION_template_haskell(2,16,0) liftTyped = genericLiftTypedCompat # endif instance (Lift a, Lift b, Lift c, Lift d) => Lift (Product' a b c d) where lift = genericLift # if MIN_VERSION_template_haskell(2,16,0) liftTyped = genericLiftTypedCompat # endif instance (Lift a, Lift b) => Lift (Sum' a b) where lift = genericLift # if MIN_VERSION_template_haskell(2,16,0) liftTyped = genericLiftTypedCompat # endif instance Lift a => Lift (Unboxed' a) where lift = genericLift # if MIN_VERSION_template_haskell(2,16,0) liftTyped = genericLiftTypedCompat # endif -- This instance shows that we can have parametric polymorphism—we don't need -- Typeable instances for @a@ or @b@. instance Lift a => Lift (Const' a b) where lift = genericLift # if MIN_VERSION_template_haskell(2,16,0) liftTyped = genericLiftTypedCompat # endif # if __GLASGOW_HASKELL__ >= 708 -- This instance demonstrates some polykindedness—the arguments to Ap' aren't -- all of kind Type. This only works for GHC 7.8 and later. instance Lift (f a) => Lift (Ap' f a) where lift = genericLift # if MIN_VERSION_template_haskell(2,16,0) liftTyped = genericLiftTypedCompat # endif # endif #endif