4 ms·
Hm... for anything real, you would need to provide good error reports, i.e. why did it fail to parse. Code like this looks pretty, but once you add in good erro
by brabel 2y ago
Hm... for anything real, you would need to provide good error reports, i.e. why did it fail to parse. Code like this looks pretty, but once you add in good error reports, I feel like it tends to look almost exactly the same as in an imperative language?
- mrkeen 2y agostrSum :: String -> Either String Int strSum = fmap sum . mapM readEither . words
- Tainnor 2y agoThat doesn't exactly give a good error message, though: > strSum "10 20 x" Left "Prelude.read: no parse" But yeah, I didn't remember "mapM". mapM f = sequence . fmap f, which is what I used.
- Tainnor 2y agoFor a real use case, consider using a parser library. If you ignore the boilerplate import stuff, it's IMHO rather short and elegant - and not very imperative: {-# LANGUAGE OverloadedStrings #-} import Data.Text (Text) import Data.Void (Void) import qualified Data.Text as T import Text.Megaparsec import Text.Megaparsec.Char import qualified Text.Megaparsec.Char.Lexer as L type Parser = Parsec Void Text numParser :: Parser [Integer] numParser = L.decimal `sepBy` space1 -- just for demonstration purposes - this will print an ugly debug string, it can be customised main = putStrLn $ show $ parse numParser "some-source-file.txt" "10 20 30 x" -- this would print "Right [10, 20, 30]" -- main = putStrLn $ show $ parse numParser "some-source-file.txt" "10 20 30"