{-# Language TemplateHaskell #-} -- from https://ocharles.org.uk/blog/guest-posts/2014-12-22-template-haskell.html import Language.Haskell.TH e1 :: IO Exp e1 = runQ [| 1 + 2 |] e2 :: Integer e2 = $( return (InfixE (Just (LitE (IntegerL 1))) (VarE (mkName "+")) (Just (LitE (IntegerL 2))) ) ) fibs :: [Integer] fibs = 0 : 1 : zipWith (+) fibs (tail fibs) fibQ :: Int -> Q Exp fibQ n = [| fibs !! n |] -- e3 gives stage restriction, need to import this module to get it -- e3 = $(fibQ 22) e4 = $(runQ [| fibs !! $( [| 8 |]) |]) e5 :: IO Exp e5 = runQ [| 1 + 2 |] e6 :: IO [Dec] e6 = runQ [d|x = 5|] e7 :: IO Type e7 = runQ [t|Int|] e8 :: IO Pat e8 = runQ [p|(x,y)|] myExp :: Q Exp; myExp = runQ [| 1 + 2 |] e9 = runQ(myExp) >>= putStrLn.pprint -- --------------------------------------------------------------------- isPrime :: (Integral a) => a -> Bool isPrime k | k <=1 = False | otherwise = not $ elem 0 (map (mod k)[2..k-1]) nextPrime :: (Integral a) => a -> a nextPrime n | isPrime n = n | otherwise = nextPrime (n+1) -- returns a list of all primes between n and m, using the nextPrime function doPrime :: (Integral a) => a -> a -> [a] doPrime n m | curr > m = [] | otherwise = curr:doPrime (curr+1) m where curr = nextPrime n -- and our Q expression primeQ :: Int -> Int -> Q Exp primeQ n m = [| doPrime n m |] -- stage restriction on e10 -- e10 = $(primeQ 0 67) -- --------------------------------------------------------------------- e11 = $(stringE . show =<< reify ''Bool) -- stage restriction e12 -- e12 = $(stringE . show =<< reify 'primeQ)