For 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"