Reputation: 5629
I want to read an input like 12 34 56
into three integers using Haskell.
For a single integer, one might use myInteger <- readLn
. But for this case, I have not found any solution, except the one of first reading a line, then replacing all spaces with ,
, (using something like:
spaceToCommas str =
let repl ' ' = ','
repl c = c
in map repl str
) and then calling read '[' ++ str ++ ']'
which feels very hackish. Also, it does not allow me to state that I want to read three integers, it will attempt to read any amount of integers from stdin.
There has to be a better way.
Note that I would like a solution that does not rely on external packages. Using e.g. Parsec is of course great, but this simple example should not require the use of a full-fledged Parser Combinator framework, right?
Upvotes: 3
Views: 1754
Reputation: 476503
What about converting the string like:
convert :: Read a => String -> [a]
convert = map read . words
words
splits the given string into a list of strings (the "words") and then we perform a read
on every element using map
.
and for instance use it like:
main = do
line <- getLine
let [a,b,c] = convert line :: [Int] in putStrLn (show (c,a,b))
or if you for instance want to read the first three elements and don't care about the rest (yes this apparently requires super-creativity skills):
main = do
line <- getLine
let (a:b:c:_) = convert line :: [Int] in putStrLn (show (c,a,b))
I here returned a tuple that is rotated one place to the right to show parsing is done.
Upvotes: 4