Permalink
Browse files

adding some commentary and a readArgsFrom so it can be mixed with opt…

…ion parsing
  • Loading branch information...
1 parent 804c812 commit 18306ac3387239c58a296020e782d2f31d869583 @rampion committed Dec 23, 2011
Showing with 66 additions and 54 deletions.
  1. +66 −54 ReadArgs.hs
View
@@ -14,18 +14,26 @@ import System.IO
-- parse the desired argument tuple from the command line or
-- print a simple usage statment and quit
readArgs :: ArgumentTuple a => IO a
-readArgs = do
- as@(~(a:_)) <- readArgsFrom `fmap` getArgs
- case as of
+readArgs = getArgs >>= readArgsFrom
+
+-- read args from the given strings or
+-- print a simple usage statment and quit
+-- (so you can do option parsing first)
+readArgsFrom :: ArgumentTuple a => [String] -> IO a
+readArgsFrom ss =
+ let as@(~(a:_)) = parseArgsFrom ss
+ in case as of
[] -> do
progName <- getProgName
- hPutStrLn stderr $ "usage: " ++ progName ++ usage a
+ hPutStrLn stderr $ "usage: " ++ progName ++ usageFor a
exitFailure
_ -> return a
-- a class for types that can be parsed from exactly one command line argument
class Arguable a where
parse :: String -> Maybe a
+ -- name's argument will usually be undefined, so when defining instances of
+ -- Arguable, it should be lazy in its argument
name :: a -> String
-- all types that are typeable and readable can be used as simple arguments
@@ -45,6 +53,8 @@ instance Arguable String where
-- arguments
class Argument a where
parseArg :: [String] -> [(a, [String])]
+ -- argName's argument will usually be undefined, so when defining instances of
+ -- Arguable, it should be lazy in its argument
argName :: a -> String
-- use the arguable tyep to just parse a single argument
@@ -86,106 +96,108 @@ instance Argument String where
-- a class for tuples of types that can be parsed from the entire list
-- of arguments
class ArgumentTuple a where
- readArgsFrom :: [String] -> [a]
- usage :: a -> String
+ parseArgsFrom :: [String] -> [a]
+ -- usageFor's argument will usually be undefined, so when defining instances of
+ -- Arguable, it should be lazy in its argument
+ usageFor :: a -> String
-- use () for no arguments
instance ArgumentTuple () where
- readArgsFrom [] = [()]
- readArgsFrom _ = []
- usage = const ""
+ parseArgsFrom [] = [()]
+ parseArgsFrom _ = []
+ usageFor = const ""
-- use :& to construct arbitrary length tuples of any parsable arguments
data a :& b = a :& b
infixr 5 :&
instance (Argument a, ArgumentTuple y) => ArgumentTuple (a :& y) where
- readArgsFrom ss = do
+ parseArgsFrom ss = do
(a, ss') <- parseArg ss
- y <- readArgsFrom ss'
+ y <- parseArgsFrom ss'
return $ a :& y
- usage ~(a :& y) = " " ++ argName a ++ usage y
+ usageFor ~(a :& y) = " " ++ argName a ++ usageFor y
-- Use :& to derive instances for all the normal tuple types
instance (Argument b, Argument a) => ArgumentTuple (b,a) where
- readArgsFrom ss = do
- b :& a :& () <- readArgsFrom ss
+ parseArgsFrom ss = do
+ b :& a :& () <- parseArgsFrom ss
return (b,a)
- usage ~(b,a) = usage (b :& a :& ())
+ usageFor ~(b,a) = usageFor (b :& a :& ())
instance (Argument c, Argument b, Argument a) => ArgumentTuple (c,b,a) where
- readArgsFrom ss = do
- c :& b :& a :& () <- readArgsFrom ss
+ parseArgsFrom ss = do
+ c :& b :& a :& () <- parseArgsFrom ss
return (c,b,a)
- usage ~(c,b,a) = usage (c :& b :& a :& ())
+ usageFor ~(c,b,a) = usageFor (c :& b :& a :& ())
instance (Argument d, Argument c, Argument b, Argument a) => ArgumentTuple (d,c,b,a) where
- readArgsFrom ss = do
- d :& c :& b :& a :& () <- readArgsFrom ss
+ parseArgsFrom ss = do
+ d :& c :& b :& a :& () <- parseArgsFrom ss
return (d,c,b,a)
- usage ~(d,c,b,a) = usage (d :& c :& b :& a :& ())
+ usageFor ~(d,c,b,a) = usageFor (d :& c :& b :& a :& ())
instance (Argument e, Argument d, Argument c, Argument b, Argument a) => ArgumentTuple (e,d,c,b,a) where
- readArgsFrom ss = do
- e :& d :& c :& b :& a :& () <- readArgsFrom ss
+ parseArgsFrom ss = do
+ e :& d :& c :& b :& a :& () <- parseArgsFrom ss
return (e,d,c,b,a)
- usage ~(e,d,c,b,a) = usage (e :& d :& c :& b :& a :& ())
+ usageFor ~(e,d,c,b,a) = usageFor (e :& d :& c :& b :& a :& ())
instance (Argument f, Argument e, Argument d, Argument c, Argument b, Argument a) => ArgumentTuple (f,e,d,c,b,a) where
- readArgsFrom ss = do
- f :& e :& d :& c :& b :& a :& () <- readArgsFrom ss
+ parseArgsFrom ss = do
+ f :& e :& d :& c :& b :& a :& () <- parseArgsFrom ss
return (f,e,d,c,b,a)
- usage ~(f,e,d,c,b,a) = usage (f :& e :& d :& c :& b :& a :& ())
+ usageFor ~(f,e,d,c,b,a) = usageFor (f :& e :& d :& c :& b :& a :& ())
instance (Argument g, Argument f, Argument e, Argument d, Argument c, Argument b, Argument a) => ArgumentTuple (g,f,e,d,c,b,a) where
- readArgsFrom ss = do
- g :& f :& e :& d :& c :& b :& a :& () <- readArgsFrom ss
+ parseArgsFrom ss = do
+ g :& f :& e :& d :& c :& b :& a :& () <- parseArgsFrom ss
return (g,f,e,d,c,b,a)
- usage ~(g,f,e,d,c,b,a) = usage (g :& f :& e :& d :& c :& b :& a :& ())
+ usageFor ~(g,f,e,d,c,b,a) = usageFor (g :& f :& e :& d :& c :& b :& a :& ())
instance (Argument h, Argument g, Argument f, Argument e, Argument d, Argument c, Argument b, Argument a) => ArgumentTuple (h,g,f,e,d,c,b,a) where
- readArgsFrom ss = do
- h :& g :& f :& e :& d :& c :& b :& a :& () <- readArgsFrom ss
+ parseArgsFrom ss = do
+ h :& g :& f :& e :& d :& c :& b :& a :& () <- parseArgsFrom ss
return (h,g,f,e,d,c,b,a)
- usage ~(h,g,f,e,d,c,b,a) = usage (h :& g :& f :& e :& d :& c :& b :& a :& ())
+ usageFor ~(h,g,f,e,d,c,b,a) = usageFor (h :& g :& f :& e :& d :& c :& b :& a :& ())
instance (Argument i, Argument h, Argument g, Argument f, Argument e, Argument d, Argument c, Argument b, Argument a) => ArgumentTuple (i,h,g,f,e,d,c,b,a) where
- readArgsFrom ss = do
- i :& h :& g :& f :& e :& d :& c :& b :& a :& () <- readArgsFrom ss
+ parseArgsFrom ss = do
+ i :& h :& g :& f :& e :& d :& c :& b :& a :& () <- parseArgsFrom ss
return (i,h,g,f,e,d,c,b,a)
- usage ~(i,h,g,f,e,d,c,b,a) = usage (i :& h :& g :& f :& e :& d :& c :& b :& a :& ())
+ usageFor ~(i,h,g,f,e,d,c,b,a) = usageFor (i :& h :& g :& f :& e :& d :& c :& b :& a :& ())
instance (Argument j, Argument i, Argument h, Argument g, Argument f, Argument e, Argument d, Argument c, Argument b, Argument a) => ArgumentTuple (j,i,h,g,f,e,d,c,b,a) where
- readArgsFrom ss = do
- j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& () <- readArgsFrom ss
+ parseArgsFrom ss = do
+ j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& () <- parseArgsFrom ss
return (j,i,h,g,f,e,d,c,b,a)
- usage ~(j,i,h,g,f,e,d,c,b,a) = usage (j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& ())
+ usageFor ~(j,i,h,g,f,e,d,c,b,a) = usageFor (j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& ())
instance (Argument k, Argument j, Argument i, Argument h, Argument g, Argument f, Argument e, Argument d, Argument c, Argument b, Argument a) => ArgumentTuple (k,j,i,h,g,f,e,d,c,b,a) where
- readArgsFrom ss = do
- k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& () <- readArgsFrom ss
+ parseArgsFrom ss = do
+ k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& () <- parseArgsFrom ss
return (k,j,i,h,g,f,e,d,c,b,a)
- usage ~(k,j,i,h,g,f,e,d,c,b,a) = usage (k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& ())
+ usageFor ~(k,j,i,h,g,f,e,d,c,b,a) = usageFor (k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& ())
instance (Argument l, Argument k, Argument j, Argument i, Argument h, Argument g, Argument f, Argument e, Argument d, Argument c, Argument b, Argument a) => ArgumentTuple (l,k,j,i,h,g,f,e,d,c,b,a) where
- readArgsFrom ss = do
- l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& () <- readArgsFrom ss
+ parseArgsFrom ss = do
+ l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& () <- parseArgsFrom ss
return (l,k,j,i,h,g,f,e,d,c,b,a)
- usage ~(l,k,j,i,h,g,f,e,d,c,b,a) = usage (l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& ())
+ usageFor ~(l,k,j,i,h,g,f,e,d,c,b,a) = usageFor (l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& ())
instance (Argument m, Argument l, Argument k, Argument j, Argument i, Argument h, Argument g, Argument f, Argument e, Argument d, Argument c, Argument b, Argument a) => ArgumentTuple (m,l,k,j,i,h,g,f,e,d,c,b,a) where
- readArgsFrom ss = do
- m :& l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& () <- readArgsFrom ss
+ parseArgsFrom ss = do
+ m :& l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& () <- parseArgsFrom ss
return (m,l,k,j,i,h,g,f,e,d,c,b,a)
- usage ~(m,l,k,j,i,h,g,f,e,d,c,b,a) = usage (m :& l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& ())
+ usageFor ~(m,l,k,j,i,h,g,f,e,d,c,b,a) = usageFor (m :& l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& ())
instance (Argument n, Argument m, Argument l, Argument k, Argument j, Argument i, Argument h, Argument g, Argument f, Argument e, Argument d, Argument c, Argument b, Argument a) => ArgumentTuple (n,m,l,k,j,i,h,g,f,e,d,c,b,a) where
- readArgsFrom ss = do
- n :& m :& l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& () <- readArgsFrom ss
+ parseArgsFrom ss = do
+ n :& m :& l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& () <- parseArgsFrom ss
return (n,m,l,k,j,i,h,g,f,e,d,c,b,a)
- usage ~(n,m,l,k,j,i,h,g,f,e,d,c,b,a) = usage (n :& m :& l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& ())
+ usageFor ~(n,m,l,k,j,i,h,g,f,e,d,c,b,a) = usageFor (n :& m :& l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& ())
instance (Argument o, Argument n, Argument m, Argument l, Argument k, Argument j, Argument i, Argument h, Argument g, Argument f, Argument e, Argument d, Argument c, Argument b, Argument a) => ArgumentTuple (o,n,m,l,k,j,i,h,g,f,e,d,c,b,a) where
- readArgsFrom ss = do
- o :& n :& m :& l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& () <- readArgsFrom ss
+ parseArgsFrom ss = do
+ o :& n :& m :& l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& () <- parseArgsFrom ss
return (o,n,m,l,k,j,i,h,g,f,e,d,c,b,a)
- usage ~(o,n,m,l,k,j,i,h,g,f,e,d,c,b,a) = usage (o :& n :& m :& l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& ())
+ usageFor ~(o,n,m,l,k,j,i,h,g,f,e,d,c,b,a) = usageFor (o :& n :& m :& l :& k :& j :& i :& h :& g :& f :& e :& d :& c :& b :& a :& ())

0 comments on commit 18306ac

Please sign in to comment.