{-# LANGUAGE TemplateHaskell, FlexibleContexts, NoMonomorphismRestriction, TypeSynonymInstances, FlexibleInstances #-} module Options.UU.Demo where import Data.Lenses.Template import Text.ParserCombinators.UU import Text.ParserCombinators.UU.BasicInstances import Text.ParserCombinators.UU.Utils import Text.ParserCombinators.UU.Interleaved import Options.UU.Interleaved import Data.Monoid import System.Environment -- We assume that we store our options in a data type for which we generate lenses data Prefers = Agda | Haskell deriving Show data Address = Address { city_ :: String , street_ :: String} deriving Show data Name = Name { name_:: String , prefers_:: Prefers , ints_ :: [Int] , address_ :: Address} deriving Show $(deriveLenses ''Name) $(deriveLenses ''Address) instance ShowParserType Prefers where showType p = " " -- The next thing to do is to specify a initial record containing the default values: defaults = Name "Atze" Haskell [] (Address "Utrecht" "Princetonplein") -- Next we define the parser for the options, by specifying for each field what may be specified: oName = name `option` ("name", pString, "Name") <> ints `options` ("ints", pNaturalRaw, "A couple of numbers") <> prefers `choose` [("agda", Agda, "In case you prefer Agda") ,("haskell", Haskell, "In case you prefer Haskell") ] <> address `field` ( city `option` ("city", pString, "Home city") <> street `option` ("street" ,pString, "Home Street" ) ) {- -- | The function `main` may serve as a template for your own option handling. You can also use this module to see what the effectis of the various ways of passing options -- >>> ./Demo -i1 --ints 2 --street=Zandlust -a -nDoaitse -i3 --ints=4 --city=Tynaarlo -- Name {name_ = "Doaitse", prefers_ = Agda, ints_ = [1,2,3,4], address_ = Address {city_ = "Tynaarlo", street_ = "Zandlust"}} -- -- >>> ./Demo -i1 --ints 2 --street=Zandlust --name Doaitse -i3 --ints=4 --city=Tynaarlo -- --name [Char] optional Name -- --ints Int recurring A couple of numbers -- Choose at least one from( -- --agda required In case you prefer Agda -- --haskell required In case you prefer Haskell -- ) -- --city [Char] optional Home city -- --street [Char] optional Home Street -- -- -- -- Correcting steps: -- -- Inserted "-a" at position 70 expecting one of ["--agda", "--agda=", "--haskell", "--haskell=", "--ints=", "--ints", "-i", "-h", "-a"] -- -- Inserted "\EOT" at position 70 expecting "\EOT" -} {- You may convert this module to a main program, and call from the command line main ::IO () main = do args <- getArgs case run defaults oName (concat (map (++ "\EOT") args)) of Left a -> case a of Succes v -> print v Help t -> putStrLn t Right errors -> putStrLn errors -- | The function `demo` can be used from within ghci: -} -- >>> demo ["-i2", "--street=Zandlust", "--ints=5", "-nAtze", "--city=Houten"] -- demo :: [[Char]] -> IO () demo args = case run defaults oName (concat (map (++ "\EOT") args)) of Left a -> case a of Succes v -> print v Help t -> putStrLn t Right errors -> putStr errors