I would like to have a getInt :: IO Int
function on Haskell. It would be a function that would take an integer from stdin, leaving the rest of the buffer intact.
The library function with this type I have found, readLn :: IO Int
, for example, would not work with an input like:
2
3 4
Because it would take the entire line 3 4
, instead of taking 3
and leaving 4
for the next getInt
. Although I know I could read the complete string and then split it using words
, I would like to ask if there is a way which does not consume the buffer.
Is there any function on the standard libraries doing this? Is there any simple/obvious way to create a getInt
I am missing?
Here I turn my comment into an answer, since it seems the original asker is okay with consuming separators. First we will define a getWord
analog to getLine
; then we will readIO
the result. We will be careful to catch EOF exceptions in case they occur.
import Control.Exception
import Control.Applicative
import Data.Char
import System.IO.Error
getWord :: IO String
getWord = handle handleEOF $ do
c <- getChar
if isSpace c then return [] else (c:) <$> getWord
where
handleEOF e = if isEOFError e then return [] else throwIO e
readWord :: Read a => IO a
readWord = getWord >>= readIO
Beware: this will of course not work well for values to be read that have a space in them (like Data.Map
s or other complex data types).