Safe String to Int conversion in Haskell (a string from the command line)

I was working on a Haskell factorial function (which turned out to be easy) and decided I wanted to write a program to prompt a user at the command line for an Int, and then do the factorial of that Int.

I quickly learned that this required a String to Int conversion in Haskell, which I wanted to do safely — I didn’t want my program to blow up. What I actually end up doing is a String to Maybe Int conversion, as you can see in this code:

-- this example shows how to read an Int from the command line, safely.
-- semi-helpful info here:

main = do

    -- prompt the user and get their input
    putStrLn "Enter an Int: "
    line <- getLine

    -- convert `line` (whose type is `String`) to a value of type `Maybe Int`
    let maybeInt = readMaybe line :: Maybe Int

    case maybeInt of
         Just n  -> putStrLn (show (factorial n)) >> main   -- `>> main` repeats the loop (asking for user input)
         Nothing -> putStrLn "Please try again."  >> main

-- converts an input `String` (i think) into a `Maybe a`.
-- in this example i use it to get a "Maybe Int" from the user's input.
readMaybe :: Read a => String -> Maybe a
readMaybe s = case reads s of
                  [(val, "")] -> Just val
                  _           -> Nothing

-- factorial function
factorial :: Int -> Int
factorial n = if n < 2 then 1 else n * factorial (n-1)

I found the readMaybe method at the Reddit URL shown in the source code. That URL doesn’t show how to do the complete String to Int conversion, but this code does. It safely converts a String to an Int by creating the integer value as a Maybe Int, which is like an Option in Scala, and is a safe way to either (a) get an Int value, or get a Nothing if the String to Int cast/conversion fails.

The Haskell reads function is an important part of this solution. It doesn’t blow up if the input string is “foo” or some other non-integer value. Search the Reddit URL I’ve shown for more details on how it works.

As a summary, if you wanted to see how to safely convert a String that you receive as user input to an Int in Haskell, I hope this code is helpful.