module AOC.Run.Interactive (
execSolution
, execSolutionWith
, testSolution
, viewPrompt
, waitForPrompt
, submitSolution
, execSolution_
, execSolutionWith_
, testSolution_
, viewPrompt_
, waitForPrompt_
, submitSolution_
, loadInput
, loadParseInput
, loadTests
, loadParseTests
, mkSpec
) where
import AOC.Challenge
import AOC.Run
import AOC.Run.Config
import AOC.Run.Load
import AOC.Solver
import AOC.Util
import Advent
import Control.Monad.Except
import Data.Bifunctor
import Data.Text (Text)
execSolution :: ChallengeSpec -> IO String
execSolution :: ChallengeSpec -> IO String
execSolution ChallengeSpec
cs = ExceptT [String] IO String -> IO String
forall a. ExceptT [String] IO a -> IO a
eitherIO (ExceptT [String] IO String -> IO String)
-> ExceptT [String] IO String -> IO String
forall a b. (a -> b) -> a -> b
$ do
Config
cfg <- IO Config -> ExceptT [String] IO Config
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Config -> ExceptT [String] IO Config)
-> IO Config -> ExceptT [String] IO Config
forall a b. (a -> b) -> a -> b
$ String -> IO Config
configFile String
defConfPath
Map Day (Map Part (Maybe Bool, Either [String] String))
out <- Config
-> MainRunOpts
-> ExceptT
[String]
IO
(Map Day (Map Part (Maybe Bool, Either [String] String)))
forall (m :: * -> *).
(MonadIO m, MonadError [String] m) =>
Config
-> MainRunOpts
-> m (Map Day (Map Part (Maybe Bool, Either [String] String)))
mainRun Config
cfg (MainRunOpts
-> ExceptT
[String]
IO
(Map Day (Map Part (Maybe Bool, Either [String] String))))
-> (TestSpec -> MainRunOpts)
-> TestSpec
-> ExceptT
[String]
IO
(Map Day (Map Part (Maybe Bool, Either [String] String)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TestSpec -> MainRunOpts
defaultMRO (TestSpec
-> ExceptT
[String]
IO
(Map Day (Map Part (Maybe Bool, Either [String] String))))
-> TestSpec
-> ExceptT
[String]
IO
(Map Day (Map Part (Maybe Bool, Either [String] String)))
forall a b. (a -> b) -> a -> b
$ ChallengeSpec -> TestSpec
TSDayPart ChallengeSpec
cs
(Maybe Bool, Either [String] String)
res <- [String]
-> Maybe (Maybe Bool, Either [String] String)
-> ExceptT [String] IO (Maybe Bool, Either [String] String)
forall e (m :: * -> *) a. MonadError e m => e -> Maybe a -> m a
maybeToEither [String
"Result not found in result map (Internal Error)"] (Maybe (Maybe Bool, Either [String] String)
-> ExceptT [String] IO (Maybe Bool, Either [String] String))
-> Maybe (Maybe Bool, Either [String] String)
-> ExceptT [String] IO (Maybe Bool, Either [String] String)
forall a b. (a -> b) -> a -> b
$
ChallengeSpec
-> Map Day (Map Part (Maybe Bool, Either [String] String))
-> Maybe (Maybe Bool, Either [String] String)
forall a. ChallengeSpec -> Map Day (Map Part a) -> Maybe a
lookupSolution ChallengeSpec
cs Map Day (Map Part (Maybe Bool, Either [String] String))
out
Either [String] String -> ExceptT [String] IO String
forall e (m :: * -> *) a. MonadError e m => Either e a -> m a
liftEither (Either [String] String -> ExceptT [String] IO String)
-> Either [String] String -> ExceptT [String] IO String
forall a b. (a -> b) -> a -> b
$ (Maybe Bool, Either [String] String) -> Either [String] String
forall a b. (a, b) -> b
snd (Maybe Bool, Either [String] String)
res
execSolutionWith
:: ChallengeSpec
-> String
-> IO String
execSolutionWith :: ChallengeSpec -> String -> IO String
execSolutionWith ChallengeSpec
cs String
inp = ExceptT [String] IO String -> IO String
forall a. ExceptT [String] IO a -> IO a
eitherIO (ExceptT [String] IO String -> IO String)
-> ExceptT [String] IO String -> IO String
forall a b. (a -> b) -> a -> b
$ do
Config
cfg <- IO Config -> ExceptT [String] IO Config
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Config -> ExceptT [String] IO Config)
-> IO Config -> ExceptT [String] IO Config
forall a b. (a -> b) -> a -> b
$ String -> IO Config
configFile String
defConfPath
Map Day (Map Part (Maybe Bool, Either [String] String))
out <- Config
-> MainRunOpts
-> ExceptT
[String]
IO
(Map Day (Map Part (Maybe Bool, Either [String] String)))
forall (m :: * -> *).
(MonadIO m, MonadError [String] m) =>
Config
-> MainRunOpts
-> m (Map Day (Map Part (Maybe Bool, Either [String] String)))
mainRun Config
cfg (MainRunOpts
-> ExceptT
[String]
IO
(Map Day (Map Part (Maybe Bool, Either [String] String))))
-> MainRunOpts
-> ExceptT
[String]
IO
(Map Day (Map Part (Maybe Bool, Either [String] String)))
forall a b. (a -> b) -> a -> b
$ (TestSpec -> MainRunOpts
defaultMRO (ChallengeSpec -> TestSpec
TSDayPart ChallengeSpec
cs))
{ _mroInput :: Day -> Part -> IO (Maybe String)
_mroInput = \Day
_ Part
_ -> Maybe String -> IO (Maybe String)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe String -> IO (Maybe String))
-> Maybe String -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$ String -> Maybe String
forall a. a -> Maybe a
Just String
inp
}
(Maybe Bool, Either [String] String)
res <- [String]
-> Maybe (Maybe Bool, Either [String] String)
-> ExceptT [String] IO (Maybe Bool, Either [String] String)
forall e (m :: * -> *) a. MonadError e m => e -> Maybe a -> m a
maybeToEither [String
"Result not found in result map (Internal Error)"] (Maybe (Maybe Bool, Either [String] String)
-> ExceptT [String] IO (Maybe Bool, Either [String] String))
-> Maybe (Maybe Bool, Either [String] String)
-> ExceptT [String] IO (Maybe Bool, Either [String] String)
forall a b. (a -> b) -> a -> b
$
ChallengeSpec
-> Map Day (Map Part (Maybe Bool, Either [String] String))
-> Maybe (Maybe Bool, Either [String] String)
forall a. ChallengeSpec -> Map Day (Map Part a) -> Maybe a
lookupSolution ChallengeSpec
cs Map Day (Map Part (Maybe Bool, Either [String] String))
out
Either [String] String -> ExceptT [String] IO String
forall e (m :: * -> *) a. MonadError e m => Either e a -> m a
liftEither (Either [String] String -> ExceptT [String] IO String)
-> Either [String] String -> ExceptT [String] IO String
forall a b. (a -> b) -> a -> b
$ (Maybe Bool, Either [String] String) -> Either [String] String
forall a b. (a, b) -> b
snd (Maybe Bool, Either [String] String)
res
testSolution :: ChallengeSpec -> IO (Maybe Bool)
testSolution :: ChallengeSpec -> IO (Maybe Bool)
testSolution ChallengeSpec
cs = ExceptT [String] IO (Maybe Bool) -> IO (Maybe Bool)
forall a. ExceptT [String] IO a -> IO a
eitherIO (ExceptT [String] IO (Maybe Bool) -> IO (Maybe Bool))
-> ExceptT [String] IO (Maybe Bool) -> IO (Maybe Bool)
forall a b. (a -> b) -> a -> b
$ do
Config
cfg <- IO Config -> ExceptT [String] IO Config
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Config -> ExceptT [String] IO Config)
-> IO Config -> ExceptT [String] IO Config
forall a b. (a -> b) -> a -> b
$ String -> IO Config
configFile String
defConfPath
Map Day (Map Part (Maybe Bool, Either [String] String))
out <- Config
-> MainRunOpts
-> ExceptT
[String]
IO
(Map Day (Map Part (Maybe Bool, Either [String] String)))
forall (m :: * -> *).
(MonadIO m, MonadError [String] m) =>
Config
-> MainRunOpts
-> m (Map Day (Map Part (Maybe Bool, Either [String] String)))
mainRun Config
cfg (MainRunOpts
-> ExceptT
[String]
IO
(Map Day (Map Part (Maybe Bool, Either [String] String))))
-> MainRunOpts
-> ExceptT
[String]
IO
(Map Day (Map Part (Maybe Bool, Either [String] String)))
forall a b. (a -> b) -> a -> b
$ (TestSpec -> MainRunOpts
defaultMRO (ChallengeSpec -> TestSpec
TSDayPart ChallengeSpec
cs))
{ _mroTest :: Bool
_mroTest = Bool
True
}
(Maybe Bool, Either [String] String)
res <- [String]
-> Maybe (Maybe Bool, Either [String] String)
-> ExceptT [String] IO (Maybe Bool, Either [String] String)
forall e (m :: * -> *) a. MonadError e m => e -> Maybe a -> m a
maybeToEither [String
"Result not found in result map (Internal Error)"] (Maybe (Maybe Bool, Either [String] String)
-> ExceptT [String] IO (Maybe Bool, Either [String] String))
-> Maybe (Maybe Bool, Either [String] String)
-> ExceptT [String] IO (Maybe Bool, Either [String] String)
forall a b. (a -> b) -> a -> b
$
ChallengeSpec
-> Map Day (Map Part (Maybe Bool, Either [String] String))
-> Maybe (Maybe Bool, Either [String] String)
forall a. ChallengeSpec -> Map Day (Map Part a) -> Maybe a
lookupSolution ChallengeSpec
cs Map Day (Map Part (Maybe Bool, Either [String] String))
out
pure $ (Maybe Bool, Either [String] String) -> Maybe Bool
forall a b. (a, b) -> a
fst (Maybe Bool, Either [String] String)
res
viewPrompt :: ChallengeSpec -> IO Text
viewPrompt :: ChallengeSpec -> IO Text
viewPrompt ChallengeSpec
cs = ExceptT [String] IO Text -> IO Text
forall a. ExceptT [String] IO a -> IO a
eitherIO (ExceptT [String] IO Text -> IO Text)
-> ExceptT [String] IO Text -> IO Text
forall a b. (a -> b) -> a -> b
$ do
Config
cfg <- IO Config -> ExceptT [String] IO Config
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Config -> ExceptT [String] IO Config)
-> IO Config -> ExceptT [String] IO Config
forall a b. (a -> b) -> a -> b
$ String -> IO Config
configFile String
defConfPath
Map Day (Map Part Text)
out <- Config
-> MainViewOpts -> ExceptT [String] IO (Map Day (Map Part Text))
forall (m :: * -> *).
(MonadIO m, MonadError [String] m) =>
Config -> MainViewOpts -> m (Map Day (Map Part Text))
mainView Config
cfg (MainViewOpts -> ExceptT [String] IO (Map Day (Map Part Text)))
-> (TestSpec -> MainViewOpts)
-> TestSpec
-> ExceptT [String] IO (Map Day (Map Part Text))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TestSpec -> MainViewOpts
defaultMVO (TestSpec -> ExceptT [String] IO (Map Day (Map Part Text)))
-> TestSpec -> ExceptT [String] IO (Map Day (Map Part Text))
forall a b. (a -> b) -> a -> b
$ ChallengeSpec -> TestSpec
TSDayPart ChallengeSpec
cs
[String] -> Maybe Text -> ExceptT [String] IO Text
forall e (m :: * -> *) a. MonadError e m => e -> Maybe a -> m a
maybeToEither [String
"Prompt not found in result map (Internal Error)"] (Maybe Text -> ExceptT [String] IO Text)
-> Maybe Text -> ExceptT [String] IO Text
forall a b. (a -> b) -> a -> b
$
ChallengeSpec -> Map Day (Map Part Text) -> Maybe Text
forall a. ChallengeSpec -> Map Day (Map Part a) -> Maybe a
lookupSolution ChallengeSpec
cs Map Day (Map Part Text)
out
waitForPrompt :: ChallengeSpec -> IO Text
waitForPrompt :: ChallengeSpec -> IO Text
waitForPrompt ChallengeSpec
cs = ExceptT [String] IO Text -> IO Text
forall a. ExceptT [String] IO a -> IO a
eitherIO (ExceptT [String] IO Text -> IO Text)
-> ExceptT [String] IO Text -> IO Text
forall a b. (a -> b) -> a -> b
$ do
Config
cfg <- IO Config -> ExceptT [String] IO Config
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Config -> ExceptT [String] IO Config)
-> IO Config -> ExceptT [String] IO Config
forall a b. (a -> b) -> a -> b
$ String -> IO Config
configFile String
defConfPath
Map Day (Map Part Text)
out <- Config
-> MainViewOpts -> ExceptT [String] IO (Map Day (Map Part Text))
forall (m :: * -> *).
(MonadIO m, MonadError [String] m) =>
Config -> MainViewOpts -> m (Map Day (Map Part Text))
mainView Config
cfg (MainViewOpts -> ExceptT [String] IO (Map Day (Map Part Text)))
-> MainViewOpts -> ExceptT [String] IO (Map Day (Map Part Text))
forall a b. (a -> b) -> a -> b
$ (TestSpec -> MainViewOpts
defaultMVO (ChallengeSpec -> TestSpec
TSDayPart ChallengeSpec
cs))
{ _mvoWait :: Bool
_mvoWait = Bool
True
}
[String] -> Maybe Text -> ExceptT [String] IO Text
forall e (m :: * -> *) a. MonadError e m => e -> Maybe a -> m a
maybeToEither [String
"Prompt not found in result map (Internal Error)"] (Maybe Text -> ExceptT [String] IO Text)
-> Maybe Text -> ExceptT [String] IO Text
forall a b. (a -> b) -> a -> b
$
ChallengeSpec -> Map Day (Map Part Text) -> Maybe Text
forall a. ChallengeSpec -> Map Day (Map Part a) -> Maybe a
lookupSolution ChallengeSpec
cs Map Day (Map Part Text)
out
submitSolution :: ChallengeSpec -> IO (Text, SubmitRes)
submitSolution :: ChallengeSpec -> IO (Text, SubmitRes)
submitSolution ChallengeSpec
cs = ExceptT [String] IO (Text, SubmitRes) -> IO (Text, SubmitRes)
forall a. ExceptT [String] IO a -> IO a
eitherIO (ExceptT [String] IO (Text, SubmitRes) -> IO (Text, SubmitRes))
-> ExceptT [String] IO (Text, SubmitRes) -> IO (Text, SubmitRes)
forall a b. (a -> b) -> a -> b
$ do
Config
cfg <- IO Config -> ExceptT [String] IO Config
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Config -> ExceptT [String] IO Config)
-> IO Config -> ExceptT [String] IO Config
forall a b. (a -> b) -> a -> b
$ String -> IO Config
configFile String
defConfPath
Config -> MainSubmitOpts -> ExceptT [String] IO (Text, SubmitRes)
forall (m :: * -> *).
(MonadIO m, MonadError [String] m) =>
Config -> MainSubmitOpts -> m (Text, SubmitRes)
mainSubmit Config
cfg (MainSubmitOpts -> ExceptT [String] IO (Text, SubmitRes))
-> MainSubmitOpts -> ExceptT [String] IO (Text, SubmitRes)
forall a b. (a -> b) -> a -> b
$ (ChallengeSpec -> MainSubmitOpts
defaultMSO ChallengeSpec
cs) { _msoRetry :: Bool
_msoRetry = Bool
True }
execSolution_ :: ChallengeSpec -> IO ()
execSolution_ :: ChallengeSpec -> IO ()
execSolution_ = IO String -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO String -> IO ())
-> (ChallengeSpec -> IO String) -> ChallengeSpec -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChallengeSpec -> IO String
execSolution
execSolutionWith_
:: ChallengeSpec
-> String
-> IO ()
execSolutionWith_ :: ChallengeSpec -> String -> IO ()
execSolutionWith_ ChallengeSpec
cs = IO String -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO String -> IO ()) -> (String -> IO String) -> String -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChallengeSpec -> String -> IO String
execSolutionWith ChallengeSpec
cs
testSolution_ :: ChallengeSpec -> IO ()
testSolution_ :: ChallengeSpec -> IO ()
testSolution_ = IO (Maybe Bool) -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO (Maybe Bool) -> IO ())
-> (ChallengeSpec -> IO (Maybe Bool)) -> ChallengeSpec -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChallengeSpec -> IO (Maybe Bool)
testSolution
viewPrompt_ :: ChallengeSpec -> IO ()
viewPrompt_ :: ChallengeSpec -> IO ()
viewPrompt_ = IO Text -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO Text -> IO ())
-> (ChallengeSpec -> IO Text) -> ChallengeSpec -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChallengeSpec -> IO Text
viewPrompt
waitForPrompt_ :: ChallengeSpec -> IO ()
waitForPrompt_ :: ChallengeSpec -> IO ()
waitForPrompt_ = IO Text -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO Text -> IO ())
-> (ChallengeSpec -> IO Text) -> ChallengeSpec -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChallengeSpec -> IO Text
waitForPrompt
submitSolution_ :: ChallengeSpec -> IO ()
submitSolution_ :: ChallengeSpec -> IO ()
submitSolution_ = IO (Text, SubmitRes) -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO (Text, SubmitRes) -> IO ())
-> (ChallengeSpec -> IO (Text, SubmitRes))
-> ChallengeSpec
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChallengeSpec -> IO (Text, SubmitRes)
submitSolution
loadParseInput :: ChallengeSpec -> a :~> b -> IO a
loadParseInput :: forall a b. ChallengeSpec -> (a :~> b) -> IO a
loadParseInput ChallengeSpec
cs a :~> b
s = ExceptT [String] IO a -> IO a
forall a. ExceptT [String] IO a -> IO a
eitherIO (ExceptT [String] IO a -> IO a) -> ExceptT [String] IO a -> IO a
forall a b. (a -> b) -> a -> b
$ do
String
i <- IO String -> ExceptT [String] IO String
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO String -> ExceptT [String] IO String)
-> IO String -> ExceptT [String] IO String
forall a b. (a -> b) -> a -> b
$ ChallengeSpec -> IO String
loadInput ChallengeSpec
cs
[String] -> Maybe a -> ExceptT [String] IO a
forall e (m :: * -> *) a. MonadError e m => e -> Maybe a -> m a
maybeToEither [String
"No parse"] (Maybe a -> ExceptT [String] IO a)
-> Maybe a -> ExceptT [String] IO a
forall a b. (a -> b) -> a -> b
$ (a :~> b) -> String -> Maybe a
forall a b. (a :~> b) -> String -> Maybe a
sParse a :~> b
s String
i
loadParseTests :: ChallengeSpec -> a :~> b -> IO [(Maybe a, TestMeta)]
loadParseTests :: forall a b. ChallengeSpec -> (a :~> b) -> IO [(Maybe a, TestMeta)]
loadParseTests ChallengeSpec
cs a :~> b
s = (((String, TestMeta) -> (Maybe a, TestMeta))
-> [(String, TestMeta)] -> [(Maybe a, TestMeta)]
forall a b. (a -> b) -> [a] -> [b]
map (((String, TestMeta) -> (Maybe a, TestMeta))
-> [(String, TestMeta)] -> [(Maybe a, TestMeta)])
-> ((String -> Maybe a)
-> (String, TestMeta) -> (Maybe a, TestMeta))
-> (String -> Maybe a)
-> [(String, TestMeta)]
-> [(Maybe a, TestMeta)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Maybe a) -> (String, TestMeta) -> (Maybe a, TestMeta)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first) ((a :~> b) -> String -> Maybe a
forall a b. (a :~> b) -> String -> Maybe a
sParse a :~> b
s) ([(String, TestMeta)] -> [(Maybe a, TestMeta)])
-> IO [(String, TestMeta)] -> IO [(Maybe a, TestMeta)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ChallengeSpec -> IO [(String, TestMeta)]
loadTests ChallengeSpec
cs
loadInput :: ChallengeSpec -> IO String
loadInput :: ChallengeSpec -> IO String
loadInput ChallengeSpec
cs = ExceptT [String] IO String -> IO String
forall a. ExceptT [String] IO a -> IO a
eitherIO (ExceptT [String] IO String -> IO String)
-> ExceptT [String] IO String -> IO String
forall a b. (a -> b) -> a -> b
$ do
CD{[(String, TestMeta)]
Maybe String
Either [String] String
Either [String] Text
_cdTests :: ChallengeData -> [(String, TestMeta)]
_cdAnswer :: ChallengeData -> Maybe String
_cdInput :: ChallengeData -> Either [String] String
_cdPrompt :: ChallengeData -> Either [String] Text
_cdTests :: [(String, TestMeta)]
_cdAnswer :: Maybe String
_cdInput :: Either [String] String
_cdPrompt :: Either [String] Text
..} <- IO ChallengeData -> ExceptT [String] IO ChallengeData
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ChallengeData -> ExceptT [String] IO ChallengeData)
-> IO ChallengeData -> ExceptT [String] IO ChallengeData
forall a b. (a -> b) -> a -> b
$ do
Cfg{Integer
Maybe String
_cfgYear :: Config -> Integer
_cfgSession :: Config -> Maybe String
_cfgYear :: Integer
_cfgSession :: Maybe String
..} <- String -> IO Config
configFile String
defConfPath
Maybe String -> Integer -> ChallengeSpec -> IO ChallengeData
challengeData Maybe String
_cfgSession Integer
_cfgYear ChallengeSpec
cs
Either [String] String -> ExceptT [String] IO String
forall e (m :: * -> *) a. MonadError e m => Either e a -> m a
liftEither Either [String] String
_cdInput
loadTests :: ChallengeSpec -> IO [(String, TestMeta)]
loadTests :: ChallengeSpec -> IO [(String, TestMeta)]
loadTests ChallengeSpec
cs = do
Cfg{Integer
Maybe String
_cfgYear :: Integer
_cfgSession :: Maybe String
_cfgYear :: Config -> Integer
_cfgSession :: Config -> Maybe String
..} <- String -> IO Config
configFile String
defConfPath
ChallengeData -> [(String, TestMeta)]
_cdTests (ChallengeData -> [(String, TestMeta)])
-> IO ChallengeData -> IO [(String, TestMeta)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe String -> Integer -> ChallengeSpec -> IO ChallengeData
challengeData Maybe String
_cfgSession Integer
_cfgYear ChallengeSpec
cs
mkSpec :: Integer -> Part -> ChallengeSpec
mkSpec :: Integer -> Part -> ChallengeSpec
mkSpec Integer
i = Day -> Part -> ChallengeSpec
CS (Integer -> Day
mkDay_ Integer
i)
eitherIO :: ExceptT [String] IO a -> IO a
eitherIO :: forall a. ExceptT [String] IO a -> IO a
eitherIO ExceptT [String] IO a
act = ExceptT [String] IO a -> IO (Either [String] a)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT ExceptT [String] IO a
act IO (Either [String] a) -> (Either [String] a -> IO a) -> IO a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Right a
x -> a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x
Left [String]
es -> String -> IO a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> IO a) -> String -> IO a
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines [String]
es