-- | A list of 'OptSpec' that works for any 'Mode'.
modeOptSpecs :: Read a => [OptSpec (Either String (GroverOpt a))]
modeOptSpecs =
  [ optSpec "z" ["zero"] . ZeroArg . Right $ Zero
  , optSpec "s" ["single"] . OneArg $ \s -> Single <$> readErr s

  , optSpec "d" ["double"] . TwoArg $ \s1 s2 ->
      Double <$> readErr s1 <*> readErr s2

  , optSpec "t" ["triple"] . ThreeArg $ \s1 s2 s3 ->
      Triple <$> readErr s1 <*> readErr s2 <*> readErr s3
  ]
modeOptSpecs :: Read a => [OptSpec (Either String (GroverOpt a))]
modeOptSpecs =
  [ optSpec "z" ["zero"] . ZeroArg . Right $ Zero
  , optSpec "s" ["single"] . OneArg $ \s -> Single <$> readErr s

  , optSpec "d" ["double"] . TwoArg $ \s1 s2 ->
      Double <$> readErr s1 <*> readErr s2

  , optSpec "t" ["triple"] . ThreeArg $ \s1 s2 s3 ->
      Triple <$> readErr s1 <*> readErr s2 <*> readErr s3
  ]
modeOptSpecs =
  [ optSpec "z" ["zero"] . ZeroArg . Right $ Zero
  , optSpec "s" ["single"] . OneArg $ \s -> Single <$> readErr s

  , optSpec "d" ["double"] . TwoArg $ \s1 s2 ->
      Double <$> readErr s1 <*> readErr s2

  , optSpec "t" ["triple"] . ThreeArg $ \s1 s2 s3 ->
      Triple <$> readErr s1 <*> readErr s2 <*> readErr s3
  ]