I'm a Haskell newbie. As a learning exercise, I'm trying to port one of my Rust programs to Haskell. In Rust, I use the amazing clap
package, and have come across Options.Applicative
as a good-looking alternative. Here's an example:
import Options.Applicative
import Data.Semigroup ((<>))
data Sample = Sample
{ tod :: Bool
, pmc :: Bool
, tai :: Bool
}
sample :: Parser Sample
sample = Sample
<$> switch
( long "tod"
<> short 'o'
<> help "Convert from TOD" )
<*> switch
( long "pmc"
<> short 'p'
<> help "Convert from PMC" )
<*> switch
( long "tai"
<> short 't'
<> help "Set TAI mode" )
main :: IO ()
main = greet =<< execParser opts
where
opts = info (sample <**> helper) ( fullDesc )
greet :: Sample -> IO ()
greet (Sample a b c) = print [a,b,c]
Having got this far, I've hit a brick wall. I need to make the "tod" and "pmc" flags mutually exclusive. There's an example in the package README which uses <|>, but it's not for boolean flags, and I don't have a clue how to transform this.
Can anyone help, please?
Make one of pmc
or tod
be a computed value, and only store the other.
data Sample = Sample
{ tod :: Bool
, tai :: Bool
}
pmc = not . tod
sample = Sample
<$> ( flag' True (short 'o')
<|> flag' False (short 'p')
<|> pure True -- what do you want to do if they specify neither?
)
<*> switch (short 't')
Or perhaps there are actually three modes of operation. Then make both tod
and pmc
be computed fields.
data Mode = TOD | PMC | Other deriving Eq
data Sample = Sample
{ mode :: Mode
, tai :: Bool
}
tod = (TOD==) . mode
pmc = (PMC==) . mode
sample = Sample
<$> ( flag' TOD (short 'o')
<|> flag' PMC (short 'p')
<|> pure Other
)
<*> switch (short 't')