How to input several values in one line in haskell
haskell
Solution
Read a line with `getLine`, split it into `words`, and `read` each:
readInts :: IO [Int]
readInts = fmap (map read.words) getLine
it reads any number of Ints:
ghci> readInts
1 2 3
[1,2,3]
ghci> readInts
1 2 3 4 5 6
[1,2,3,4,5,6]
You could restrict to three:
read3Ints :: IO [Int]
read3Ints = do
ints <- readInts
if length ints == 3 then return ints else do
putStrLn ("sorry, could you give me exactly three integers, "
++ "separated by spaces?")
read3Ints
which looks like this:
ghci> read3Ints
1 2
sorry, could you give me exactly three integers, separated by spaces?
1 23 , 5, 6
sorry, could you give me exactly three integers, separated by spaces?
1,2,3
sorry, could you give me exactly three integers, separated by spaces?
1 3 6
The secrets of `fmap`
`fmap` works a bit like `map`, but you can use it more widely:
ghci> fmap (*10) [1,2,3,4]
[10,20,30,40]
ghci> fmap (*10) (Just 5)
Just 50
ghci> map (fmap (*10)) [Left 'b', Right 4, Left 'c', Right 7]
[Left 'b',Right 40,Left 'c',Right 70]
ghci> fmap words getLine
Hello there me hearties!
["Hello","there","me","hearties!"]
In `getInts`, I did `fmap (map read.words)` to split the line by spaces, then `map read` to turn each one into an `Int`. The compiler knows I wanted `Int` because of the type signature - I'd get an error if I omitted it.
Problem
For example, I want to write a program which will take 3 integers as input from command line. The functions I have learned is `readLn` to read values from entire line. But `readLn` seems to parse the entire line as a single value. How can I get the three values of one line with haskell?