Hi Jeff
It sounds like maybe you just want an application that works a bit like 'cabal'.
So with cabal the first argument is taken as the 'command' and then the rest
are based on that:
cabal build --some other --options --which may --or --may --not have --arguments
Yi has a simple template for a script which should get you started, please find
it attached.
So here instead of processOptions, you might want, processCommand
processCommand :: [ String ] -> IO ()
processCommand ("build" : args) = processBuildCommand args
processCommand ("play" : args) = processPlayCommand args
processCommand [] = putStrLn "You must supply a command"
processCommand _ = putStrLn "Sorry I don't understand your
command" --Probably out put help here as well
processBuildCommand :: [ String ] -> IO ()
processBuildCommand = similar to the processOptions except now you are sure you
are in a 'build' command
you *might* even have a separate set of option descreptions for each command.
hth
allan
Jeff Wheeler wrote:
> Hi,
>
> I'm a slight Haskell newbie, but I'm trying to write a terminal-like
> application that accepts simple commands with optional arguments, and
> can then execute them. Most of these commands will need IO, as later I
> will want to communicate over USB for most of them.
>
> I was hoping, though, that I could get some comments on the initial
> architecture I've been playing with [1].
>
> I suspect I should be using some sort of monad to represent the
> commands, but I don't fully understand monads, and am not sure how it
> would apply in this context.
>
> Should I be using a monad here, and if so, how?
>
> Thanks in advance,
> Jeff Wheeler
>
> [1] http://media.nokrev.com/junk/cli/
> _______________________________________________
> Haskell-Cafe mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
--
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.
{-
-}
module Main
( main )
where
{- Standard Library Modules Imported -}
import System.Console.GetOpt
( getOpt
, usageInfo
, ArgOrder ( .. )
, OptDescr ( .. )
, ArgDescr ( .. )
)
import System.Environment
( getArgs
, getProgName
)
{- External Library Modules Imported -}
{- Local Modules Imported -}
{- End of Imports -}
data CliFlag =
CliHelp
| CliVersion
deriving Eq
options :: [ OptDescr CliFlag ]
options =
[ Option "h" [ "help" ]
(NoArg CliHelp)
"Print the help message to standard out and then exit"
, Option "v" [ "version" ]
(NoArg CliVersion)
"Print out the version of this program"
]
helpMessage :: String -> String
helpMessage progName =
usageInfo progName options
versionMessage :: String -> String
versionMessage progName =
progName ++ ": This is version 0.001"
-- | The main exported function
main :: IO ()
main = getArgs >>= processOptions
processOptions :: [ String ] -> IO ()
processOptions cliArgs =
case getOpt Permute options cliArgs of
(flags, args, []) ->
processArgs flags args
(_flags, _args, errors) ->
do progName <- getProgName
ioError $ userError (concat errors ++ helpMessage progName)
-- We assume all of the arguments are files to process
processArgs :: [ CliFlag ] -> [ String ] -> IO ()
processArgs flags files
| elem CliHelp flags = getProgName >>= (putStrLn . helpMessage)
| elem CliVersion flags = getProgName >>= (putStrLn . versionMessage)
| otherwise = mapM_ processFile files
-- Our processing of a file is to simply count the words
-- in the file and output the number as a line.
processFile :: FilePath -> IO ()
processFile file =
do contents <- readFile file
putStrLn (show $ length $ words contents)
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe