tup-functor 0.2.0.2 → 0.2.0.3
raw patch · 3 files changed
+414/−342 lines, 3 files
Files
- Data/Tup/Tup/Concat.hs +164/−95
- preprocessor/tpp.hs +200/−197
- tup-functor.cabal +50/−50
Data/Tup/Tup/Concat.hs view
@@ -1,95 +1,164 @@- --- | Concatenation of tuples. Requires MPTCs and FunDeps. - -{-# OPTIONS_GHC -cpp -pgmPcpphs -optP--cpp -optP-ansi -optP--hashes #-} -{-# LANGUAGE CPP, MultiParamTypeClasses, FunctionalDependencies #-} -module Data.Tup.Tup.Concat where - --------------------------------------------------------------------------------- - -import Data.Tup.Tup.Class - -import qualified Data.Tup.Tup.Lazy as L -import qualified Data.Tup.Tup.Strict as S - --------------------------------------------------------------------------------- - -class (Tup f, Tup g, Tup h) => TupConcat f g h | f g -> h where - tupConcat :: f a -> g a -> h a - tupConcat x y = tupFromList (tupToList x ++ tupToList y) - --------------------------------------------------------------------------------- - -#define TUPCONCAT(A,B,C) \ -instance TupConcat L.Tup##A L.Tup##B L.Tup##C where { } ; \ -instance TupConcat S.Tup##A S.Tup##B S.Tup##C where { } - --------------------------------------------------------------------------------- - -TUPCONCAT(0,0,0) -TUPCONCAT(0,1,1) -TUPCONCAT(0,2,2) -TUPCONCAT(0,3,3) -TUPCONCAT(0,4,4) -TUPCONCAT(0,5,5) -TUPCONCAT(0,6,6) -TUPCONCAT(0,7,7) -TUPCONCAT(0,8,8) -TUPCONCAT(0,9,9) - -TUPCONCAT(1,0,1) -TUPCONCAT(1,1,2) -TUPCONCAT(1,2,3) -TUPCONCAT(1,3,4) -TUPCONCAT(1,4,5) -TUPCONCAT(1,5,6) -TUPCONCAT(1,6,7) -TUPCONCAT(1,7,8) -TUPCONCAT(1,8,9) - -TUPCONCAT(2,0,2) -TUPCONCAT(2,1,3) -TUPCONCAT(2,2,4) -TUPCONCAT(2,3,5) -TUPCONCAT(2,4,6) -TUPCONCAT(2,5,7) -TUPCONCAT(2,6,8) -TUPCONCAT(2,7,9) - -TUPCONCAT(3,0,3) -TUPCONCAT(3,1,4) -TUPCONCAT(3,2,5) -TUPCONCAT(3,3,6) -TUPCONCAT(3,4,7) -TUPCONCAT(3,5,8) -TUPCONCAT(3,6,9) - -TUPCONCAT(4,0,4) -TUPCONCAT(4,1,5) -TUPCONCAT(4,2,6) -TUPCONCAT(4,3,7) -TUPCONCAT(4,4,8) -TUPCONCAT(4,5,9) - -TUPCONCAT(5,0,5) -TUPCONCAT(5,1,6) -TUPCONCAT(5,2,7) -TUPCONCAT(5,3,8) -TUPCONCAT(5,4,9) - -TUPCONCAT(6,0,6) -TUPCONCAT(6,1,7) -TUPCONCAT(6,2,8) -TUPCONCAT(6,3,9) - -TUPCONCAT(7,0,7) -TUPCONCAT(7,1,8) -TUPCONCAT(7,2,9) - -TUPCONCAT(8,0,8) -TUPCONCAT(8,1,9) - -TUPCONCAT(9,0,9) - --------------------------------------------------------------------------------- - ++-- | Concatenation of tuples. Requires MPTCs and FunDeps. ++{-# OPTIONS_GHC -cpp -pgmPcpphs -optP--cpp -optP-ansi -optP--hashes #-}+{-# LANGUAGE CPP, MultiParamTypeClasses, FunctionalDependencies #-}+module Data.Tup.Tup.Concat where++--------------------------------------------------------------------------------++import Data.Tup.Tup.Class++import qualified Data.Tup.Tup.Lazy as L+import qualified Data.Tup.Tup.Strict as S++--------------------------------------------------------------------------------++class (Tup f, Tup g, Tup h) => TupConcat f g h | f g -> h where+ tupConcat :: f a -> g a -> h a+ tupConcat x y = tupFromList (tupToList x ++ tupToList y)++--------------------------------------------------------------------------------++#define TUPCONCAT_L(A,B,C) \+instance TupConcat L.Tup##A L.Tup##B L.Tup##C ++#define TUPCONCAT_S(A,B,C) \+instance TupConcat S.Tup##A S.Tup##B S.Tup##C ++--------------------------------------------------------------------------------++TUPCONCAT_L(0,0,0)+TUPCONCAT_L(0,1,1)+TUPCONCAT_L(0,2,2)+TUPCONCAT_L(0,3,3)+TUPCONCAT_L(0,4,4)+TUPCONCAT_L(0,5,5)+TUPCONCAT_L(0,6,6)+TUPCONCAT_L(0,7,7)+TUPCONCAT_L(0,8,8)+TUPCONCAT_L(0,9,9)++TUPCONCAT_L(1,0,1)+TUPCONCAT_L(1,1,2)+TUPCONCAT_L(1,2,3)+TUPCONCAT_L(1,3,4)+TUPCONCAT_L(1,4,5)+TUPCONCAT_L(1,5,6)+TUPCONCAT_L(1,6,7)+TUPCONCAT_L(1,7,8)+TUPCONCAT_L(1,8,9)++TUPCONCAT_L(2,0,2)+TUPCONCAT_L(2,1,3)+TUPCONCAT_L(2,2,4)+TUPCONCAT_L(2,3,5)+TUPCONCAT_L(2,4,6)+TUPCONCAT_L(2,5,7)+TUPCONCAT_L(2,6,8)+TUPCONCAT_L(2,7,9)++TUPCONCAT_L(3,0,3)+TUPCONCAT_L(3,1,4)+TUPCONCAT_L(3,2,5)+TUPCONCAT_L(3,3,6)+TUPCONCAT_L(3,4,7)+TUPCONCAT_L(3,5,8)+TUPCONCAT_L(3,6,9)++TUPCONCAT_L(4,0,4)+TUPCONCAT_L(4,1,5)+TUPCONCAT_L(4,2,6)+TUPCONCAT_L(4,3,7)+TUPCONCAT_L(4,4,8)+TUPCONCAT_L(4,5,9)++TUPCONCAT_L(5,0,5)+TUPCONCAT_L(5,1,6)+TUPCONCAT_L(5,2,7)+TUPCONCAT_L(5,3,8)+TUPCONCAT_L(5,4,9)++TUPCONCAT_L(6,0,6)+TUPCONCAT_L(6,1,7)+TUPCONCAT_L(6,2,8)+TUPCONCAT_L(6,3,9)++TUPCONCAT_L(7,0,7)+TUPCONCAT_L(7,1,8)+TUPCONCAT_L(7,2,9)++TUPCONCAT_L(8,0,8)+TUPCONCAT_L(8,1,9)++TUPCONCAT_L(9,0,9)++--------------------------------------------------------------------------------++TUPCONCAT_S(0,0,0)+TUPCONCAT_S(0,1,1)+TUPCONCAT_S(0,2,2)+TUPCONCAT_S(0,3,3)+TUPCONCAT_S(0,4,4)+TUPCONCAT_S(0,5,5)+TUPCONCAT_S(0,6,6)+TUPCONCAT_S(0,7,7)+TUPCONCAT_S(0,8,8)+TUPCONCAT_S(0,9,9)++TUPCONCAT_S(1,0,1)+TUPCONCAT_S(1,1,2)+TUPCONCAT_S(1,2,3)+TUPCONCAT_S(1,3,4)+TUPCONCAT_S(1,4,5)+TUPCONCAT_S(1,5,6)+TUPCONCAT_S(1,6,7)+TUPCONCAT_S(1,7,8)+TUPCONCAT_S(1,8,9)++TUPCONCAT_S(2,0,2)+TUPCONCAT_S(2,1,3)+TUPCONCAT_S(2,2,4)+TUPCONCAT_S(2,3,5)+TUPCONCAT_S(2,4,6)+TUPCONCAT_S(2,5,7)+TUPCONCAT_S(2,6,8)+TUPCONCAT_S(2,7,9)++TUPCONCAT_S(3,0,3)+TUPCONCAT_S(3,1,4)+TUPCONCAT_S(3,2,5)+TUPCONCAT_S(3,3,6)+TUPCONCAT_S(3,4,7)+TUPCONCAT_S(3,5,8)+TUPCONCAT_S(3,6,9)++TUPCONCAT_S(4,0,4)+TUPCONCAT_S(4,1,5)+TUPCONCAT_S(4,2,6)+TUPCONCAT_S(4,3,7)+TUPCONCAT_S(4,4,8)+TUPCONCAT_S(4,5,9)++TUPCONCAT_S(5,0,5)+TUPCONCAT_S(5,1,6)+TUPCONCAT_S(5,2,7)+TUPCONCAT_S(5,3,8)+TUPCONCAT_S(5,4,9)++TUPCONCAT_S(6,0,6)+TUPCONCAT_S(6,1,7)+TUPCONCAT_S(6,2,8)+TUPCONCAT_S(6,3,9)++TUPCONCAT_S(7,0,7)+TUPCONCAT_S(7,1,8)+TUPCONCAT_S(7,2,9)++TUPCONCAT_S(8,0,8)+TUPCONCAT_S(8,1,9)++TUPCONCAT_S(9,0,9)++--------------------------------------------------------------------------------+
preprocessor/tpp.hs view
@@ -1,197 +1,200 @@- --- | Tuple brackets preprocessor. --- Use like this: --- --- > {-# OPTIONS -F -pgmF tuplepp -optF --tup #-} --- > {-# OPTIONS -F -pgmF tuplepp -optF --vec #-} --- --- Write code like this: --- --- > x = {{a,b,c}} --- --- and it will be translated to one of these: --- --- > x = Tup3 a b c --- > x = (Cons a (Cons b (Cons c Empty))) --- -{-# LANGUAGE PackageImports #-} -module Main where - --------------------------------------------------------------------------------- - -import Data.Char -import Data.List (intersect) - -import Language.Haskell.Exts -import "parsec2" Text.ParserCombinators.Parsec - -import System.Environment - --- import Debug.Trace --- debug x = trace (show x) - --------------------------------------------------------------------------------- - -constructor :: String -> Exp -constructor con = Var $ UnQual $ Ident (con) - -toVecListE :: Exp -> Exp -toVecListE e = - case e of - Con (Special UnitCon) -> go [] - Tuple es -> go es - _ -> go [e] - where - go [] = constructor "Empty" - go (x:xs) = App (App (constructor "Cons") x) (go xs) - --------------------------------------------------------------------------------- - -tupleCon :: Int -> Exp -tupleCon k = Var $ UnQual $ Ident ("Tup" ++ show k) - -toTupleE :: Exp -> Exp -toTupleE e = case e of - Con (Special UnitCon) -> tupleCon 0 - Tuple es -> foldl App (tupleCon (length es)) es - _ -> App (tupleCon 1) e - -inparens :: String -> String -inparens s = "(" ++ s ++ ")" - -toTupleS :: Cfg -> String -> String -toTupleS cfg s = {- trace ("|"++s++"|") $ -} case parseExp (inparens s) of - ParseOk e -> case cfg of - TupPP -> pp (toTupleE e) - VecPP -> pp (toVecListE e) - err -> error ("tuplepp: parse error in tuple bracket:\n" ++ show err) - -pp :: Pretty a => a -> String -pp = prettyPrintStyleMode style mode where - mode = defaultMode - { layout = PPNoLayout - } - style = Style - { mode = LeftMode -- OneLineMode - , lineLength = 1000 - , ribbonsPerLine = 1.5 - } - --------------------------------------------------------------------------------- - -data TupleLine - = S String - | I TupleLine (Bool,TupleLine) TupleLine -- pre (isTuple,bracket) post - deriving Show - -{- -xinit :: TupleLine -> TupleLine -xinit (S str) = S (init str) -xinit (I pre mid post) = I pre mid (xinit post) - -xtail :: TupleLine -> TupleLine -xtail (S str) = S (tail str) -xtail (I pre mid post) = I (xtail pre) mid post --} - -lineP :: Parser TupleLine -lineP = do - pre <- many (noneOf "{}") - m <- optionMaybe $ do - - char '{' - c <- lookAhead anyChar - mid <- case c of - '{' -> char '{' >> lineP - _ -> lineP - - char '}' - d <- lookAhead anyChar - post <- case d of - '}' -> char '}' >> lineP - _ -> lineP - - let b = (c=='{') && (d=='}') -- True -- if isAlphaNum c || elem c "({[_" then True else False - - return (b,mid,post) - return $ case m of - Nothing -> S pre - Just (b,mid,post) -> case b of - True -> I (S pre) (b,mid) (post) - False -> I (S pre) (b,mid) (post) - -parseLine :: SourceName -> String -> TupleLine -parseLine src s = case runParser lineP () "" s of - Right xx -> xx - Left err -> error ("tuplepp: preprocessor parse error in file \"" ++ src ++ "\":\n" ++ show err) - -convertTupleLine :: Cfg -> TupleLine -> String -convertTupleLine cfg (S ln) = ln -convertTupleLine cfg (I pre (b,mid) post) = pre' ++ mid'' ++ post' where - pre' = convertTupleLine cfg pre - mid' = convertTupleLine cfg mid - post' = convertTupleLine cfg post - mid'' = if b - then '(' : toTupleS cfg mid' ++ ")" - else "{" ++ mid' ++ "}" - -processLine :: Cfg -> SourceName -> String -> String -processLine cfg src = convertTupleLine cfg . parseLine src - --------------------------------------------------------------------------------- - -data Cfg = TupPP | VecPP deriving (Eq,Show) - -tupCfg, vecCfg :: Cfg -tupCfg = TupPP -vecCfg = VecPP - -tupOpts, vecOpts, possibleOpts :: [String] -tupOpts = [ "-t" , "--tup" ] -vecOpts = [ "-v" , "--vec" ] -possibleOpts = vecOpts ++ tupOpts - -main :: IO () -main = - do - args0 <- getArgs - let opts = filter (\x -> x `elem` possibleOpts ) args0 - args = filter (\x -> not (x `elem` possibleOpts)) args0 - let vecMode = not (null opts) - let cfg | null opts = tupCfg -- default is tup - | not (null (intersect opts tupOpts)) = tupCfg - | not (null (intersect opts vecOpts)) = vecCfg - | True = error "tuplepp: fatal error while parsing the options" - - case args of - - [] -> interact (f cfg "stdin") - [inp] -> do - text <- readFile inp - putStrLn $ f cfg inp text - [inp,out] -> do - text <- readFile inp - writeFile out $ f cfg inp text - [inp,cpp,out] -> do -- ghc calls the preprocessor this way - text <- readFile cpp - let pptext = f cfg cpp text - writeFile out pptext - - _ -> do - print args - putStrLn $ unlines - [ "usage:" - , " tuplepp [options] <input.hs >output.hs" - , " tuplepp [options] input.hs >output.hs" - , " tuplepp [options] input.hs output.hs" - , " tuplepp [options] dummy.hs input.hs output.hs -- this is for GHC" - , "options:" - , " -t, --tup : generates (Tup3 105 106 106) expressions" - , " -v, --vec : generates (vec3 105 106 106) expressions" - ] - - where - f cfg src text = processLine cfg src text - --------------------------------------------------------------------------------- - ++-- | Tuple brackets preprocessor.+-- Use like this:+-- +-- > {-# OPTIONS -F -pgmF tuplepp -optF --tup #-}+-- > {-# OPTIONS -F -pgmF tuplepp -optF --vec #-}+--+-- Write code like this:+--+-- > x = {{a,b,c}}+--+-- and it will be translated to one of these:+--+-- > x = (Tup3 a b c)+-- > x = (Cons a (Cons b (Cons c Empty)))+-- +-- This should also work in pattern context.+--++{-# LANGUAGE PackageImports #-}+module Main where++--------------------------------------------------------------------------------++import Data.Char+import Data.List (intersect)++import Language.Haskell.Exts+import "parsec2" Text.ParserCombinators.Parsec++import System.Environment++-- import Debug.Trace+-- debug x = trace (show x)++--------------------------------------------------------------------------------++constructor :: String -> Exp+constructor con = Var $ UnQual $ Ident (con)++toVecListE :: Exp -> Exp+toVecListE e = + case e of+ Con (Special UnitCon) -> go []+ Tuple es -> go es + _ -> go [e]+ where+ go [] = constructor "Empty"+ go (x:xs) = App (App (constructor "Cons") x) (go xs)++--------------------------------------------------------------------------------++tupleCon :: Int -> Exp+tupleCon k = Var $ UnQual $ Ident ("Tup" ++ show k)++toTupleE :: Exp -> Exp+toTupleE e = case e of+ Con (Special UnitCon) -> tupleCon 0+ Tuple es -> foldl App (tupleCon (length es)) es+ _ -> App (tupleCon 1) e++inparens :: String -> String+inparens s = "(" ++ s ++ ")"++toTupleS :: Cfg -> String -> String+toTupleS cfg s = {- trace ("|"++s++"|") $ -} case parseExp (inparens s) of+ ParseOk e -> case cfg of+ TupPP -> pp (toTupleE e)+ VecPP -> pp (toVecListE e)+ err -> error ("tuplepp: parse error in tuple bracket:\n" ++ show err)++pp :: Pretty a => a -> String+pp = prettyPrintStyleMode style mode where+ mode = defaultMode+ { layout = PPNoLayout+ }+ style = Style + { mode = LeftMode -- OneLineMode+ , lineLength = 1000+ , ribbonsPerLine = 1.5+ }+ +--------------------------------------------------------------------------------++data TupleLine + = S String+ | I TupleLine (Bool,TupleLine) TupleLine -- pre (isTuple,bracket) post+ deriving Show++{-+xinit :: TupleLine -> TupleLine+xinit (S str) = S (init str)+xinit (I pre mid post) = I pre mid (xinit post)++xtail :: TupleLine -> TupleLine+xtail (S str) = S (tail str)+xtail (I pre mid post) = I (xtail pre) mid post+-}++lineP :: Parser TupleLine+lineP = do+ pre <- many (noneOf "{}") + m <- optionMaybe $ do++ char '{'+ c <- lookAhead anyChar+ mid <- case c of+ '{' -> char '{' >> lineP+ _ -> lineP++ char '}'+ d <- lookAhead anyChar+ post <- case d of+ '}' -> char '}' >> lineP+ _ -> lineP++ let b = (c=='{') && (d=='}') -- True -- if isAlphaNum c || elem c "({[_" then True else False++ return (b,mid,post)+ return $ case m of+ Nothing -> S pre+ Just (b,mid,post) -> case b of+ True -> I (S pre) (b,mid) (post)+ False -> I (S pre) (b,mid) (post)++parseLine :: SourceName -> String -> TupleLine+parseLine src s = case runParser lineP () "" s of+ Right xx -> xx+ Left err -> error ("tuplepp: preprocessor parse error in file \"" ++ src ++ "\":\n" ++ show err)++convertTupleLine :: Cfg -> TupleLine -> String+convertTupleLine cfg (S ln) = ln+convertTupleLine cfg (I pre (b,mid) post) = pre' ++ mid'' ++ post' where+ pre' = convertTupleLine cfg pre+ mid' = convertTupleLine cfg mid+ post' = convertTupleLine cfg post+ mid'' = if b + then '(' : toTupleS cfg mid' ++ ")"+ else "{" ++ mid' ++ "}"+ +processLine :: Cfg -> SourceName -> String -> String +processLine cfg src = convertTupleLine cfg . parseLine src+ +-------------------------------------------------------------------------------- ++data Cfg = TupPP | VecPP deriving (Eq,Show)++tupCfg, vecCfg :: Cfg+tupCfg = TupPP+vecCfg = VecPP++tupOpts, vecOpts, possibleOpts :: [String]+tupOpts = [ "-t" , "--tup" ] +vecOpts = [ "-v" , "--vec" ]+possibleOpts = vecOpts ++ tupOpts++main :: IO ()+main = + do+ args0 <- getArgs+ let opts = filter (\x -> x `elem` possibleOpts ) args0+ args = filter (\x -> not (x `elem` possibleOpts)) args0+ let vecMode = not (null opts)+ let cfg | null opts = tupCfg -- default is tup+ | not (null (intersect opts tupOpts)) = tupCfg+ | not (null (intersect opts vecOpts)) = vecCfg+ | True = error "tuplepp: fatal error while parsing the options"++ case args of++ [] -> interact (f cfg "stdin")+ [inp] -> do+ text <- readFile inp+ putStrLn $ f cfg inp text+ [inp,out] -> do+ text <- readFile inp+ writeFile out $ f cfg inp text+ [inp,cpp,out] -> do -- ghc calls the preprocessor this way+ text <- readFile cpp+ let pptext = f cfg cpp text+ writeFile out pptext++ _ -> do+ -- print args+ putStrLn $ unlines+ [ "usage:"+ , " tuplepp [options] <input.hs >output.hs"+ , " tuplepp [options] input.hs >output.hs"+ , " tuplepp [options] input.hs output.hs"+ , " tuplepp [options] dummy.hs input.hs output.hs -- this is for GHC"+ , "options:"+ , " -t, --tup : generates (Tup3 105 106 107) expressions/patterns"+ , " -v, --vec : generates (Cons 105 (Cons 106 (Cons 107 Empty))) expressions/patterns"+ ]+ + where+ f cfg src text = processLine cfg src text++-------------------------------------------------------------------------------- +
tup-functor.cabal view
@@ -1,51 +1,51 @@- -Name: tup-functor -Version: 0.2.0.2 -Synopsis: Homogeneous tuples -Description: Homogeneous tuples (also known as vectors), with various instances, most notably 'Functor' and 'Applicative'. - The primary goal of the library is to help functor-oriented programming - (for low-dimensional linear algebra, there are more specific packages, eg. @vect@). - A small preprocessor for a tuple syntax is also included. We also provide a different implementation - using type-level programming. -Author: Balazs Komuves -license: BSD3 -license-file: LICENSE -Copyright: (c) 2012 Balazs Komuves -Maintainer: bkomuves (plus) hackage (at) gmail (dot) hu -Homepage: http://code.haskell.org/~bkomuves/ -Stability: Experimental -Category: Data -Tested-With: GHC == 7.0.3 -Cabal-Version: >= 1.6 -Build-Type: Simple - -extra-source-files: Data/Tup/Tup/Tup.inc - -source-repository head - type: darcs - location: http://code.haskell.org/~bkomuves/projects/tup-functor/ - -Library - Build-Depends: base >= 3 && < 5, cpphs >= 1.3 - - Exposed-Modules: Data.Tup - Data.Tup.Vec - Data.Tup.Tup - Data.Tup.Tup.Class - Data.Tup.Tup.Strict - Data.Tup.Tup.Lazy - Data.Tup.Tup.Concat - - Extensions: CPP - Hs-Source-Dirs: . - - -- force-recomp is necessary since all the source code is included via the C preprocessor, - -- and thus the recompilation checker is broken - ghc-options: -fforce-recomp -Wall -fno-warn-unused-matches -fno-warn-unused-imports -fno-warn-unused-binds - -Executable tuplepp - Build-Depends: base >= 3 && < 5, parsec2, haskell-src-exts - Main-is: preprocessor/tpp.hs - Hs-Source-Dirs: . - ghc-options: -Wall -fno-warn-unused-matches -fno-warn-unused-imports -fno-warn-unused-binds -fno-warn-unused-do-bind ++Name: tup-functor+Version: 0.2.0.3+Synopsis: Homogeneous tuples+Description: Homogeneous tuples (also known as vectors), with various instances, most notably 'Functor' and 'Applicative'.+ The primary goal of the library is to help functor-oriented programming + (for low-dimensional linear algebra, there are more specific packages, eg. @vect@). + A small preprocessor for a tuple syntax is also included. We also provide a different implementation + using type-level programming.+Author: Balazs Komuves+license: BSD3+license-file: LICENSE+Copyright: (c) 2012 Balazs Komuves+Maintainer: bkomuves (plus) hackage (at) gmail (dot) hu+Homepage: http://code.haskell.org/~bkomuves/+Stability: Experimental+Category: Data+Tested-With: GHC == 7.0.3+Cabal-Version: >= 1.6+Build-Type: Simple++extra-source-files: Data/Tup/Tup/Tup.inc++source-repository head+ type: darcs+ location: http://code.haskell.org/~bkomuves/projects/tup-functor/+ +Library+ Build-Depends: base >= 3 && < 5, cpphs >= 1.3++ Exposed-Modules: Data.Tup+ Data.Tup.Vec+ Data.Tup.Tup+ Data.Tup.Tup.Class+ Data.Tup.Tup.Strict+ Data.Tup.Tup.Lazy+ Data.Tup.Tup.Concat++ Extensions: CPP+ Hs-Source-Dirs: .++ -- force-recomp is necessary since all the source code is included via the C preprocessor, + -- and thus the recompilation checker is broken+ ghc-options: -fforce-recomp -Wall -fno-warn-unused-matches -fno-warn-unused-imports -fno-warn-unused-binds+ +Executable tuplepp+ Build-Depends: base >= 3 && < 5, parsec2, haskell-src-exts + Main-is: preprocessor/tpp.hs+ Hs-Source-Dirs: .+ ghc-options: -Wall -fno-warn-unused-matches -fno-warn-unused-imports -fno-warn-unused-binds -fno-warn-unused-do-bind