data ReadError
= IllegalFormat
| ParseFailure Text
| RefineError !RefineException
type RecordParser = StateT CategoryName Parser
data Record = Record
{ recordName :: CardName
, recordCopies :: PositiveNumber
, recordCategory :: CategoryName
}
do
ch <- anyChar
remaining <- T.pack <$> manyTill anyChar (endOfLine <|> endOfInput)
return . NonEmptyText . reallyUnsafeRefine $ T.cons ch remaining
do
num <- decimal
if num == 0
then fail "not a positive number"
else return . PositiveNumber . reallyUnsafeRefine $ num
do
recordCopies <- copiesP
void $ optional $ char 'x'
skipSpace
recordName <- cardNameP
return $ Record {recordName, recordCopies, recordCategory}
do
mb <- lift $ manyTill (recordP mainboard) (endOfLine <|> endOfInput)
lift skipSpace
sb <- lift $ manyTill (recordP sideboard) (endOfLine <|> endOfInput)
return $ mb ++ sb
do
res <- mapLeft (const [IllegalFormat]) $ decodeUtf8' content
fromText res
let parsed =
mapLeft (singleton . ParseFailure . T.pack) . flip parseOnly content $
(evalStateT decklistP mainboard <* endOfInput)
in map (\Record {..} -> add recordName recordCategory recordCopies) <$> parsed
let f = eval . evalMany
in curry (f *** f)
TIO.readFile p <&> fromText
do
oldTask <- async (fmap (eval . evalMany) <$> readDeckList oldFile)
newTask <- async (fmap (eval . evalMany) <$> readDeckList newFile)
finished <- waitEither oldTask newTask
case finished of
Left (Left e) -> cancel newTask >> pure (Left e)
Right (Left e) -> cancel oldTask >> pure (Left e)
Left (Right x) -> do
y <- wait newTask
case y of
Left e -> pure $ Left e
Right n -> pure . Right $ (x, n)
Right (Right x) -> do
y <- wait oldTask
case y of
Left e -> pure $ Left e
Right n -> pure . Right $ (n, x)