I'm coding in Haskell for the first time, and I'm having trouble with case statements.
points = do
pts <- try(readLn :: IO Int) :: IO (Either SomeException Int)
case pts of
Left ex -> putStrLn "Please enter a number."
Right val -> return pts
This code is for reading an integer from user input, and checking to make sure it is indeed an int. The issue I'm having is with the Left ex case. What I want to do is, if there's an exception, to print the line "Please enter a number." and then run the points function again. The issue is that I can't figure out how to call points within the Left ex case, as it interferes with the print statement. Any guidance?
CodePudding user response:
You can use the do
notation, which allows to glue several IO
(or another monad's) actions in order, like you're already doing in the body of points
itself:
points = do
pts <- try(readLn :: IO Int) :: IO (Either SomeException Int)
case pts of
Left ex -> do
putStrLn "Please enter a number."
points
Right val -> return pts
Alternatively, you could do what the do
notation does under the hood, and use the >>=
operator, which is what glues two IO
actions in order:
points = do
pts <- try(readLn :: IO Int) :: IO (Either SomeException Int)
case pts of
Left ex -> putStrLn "Please enter a number." >>= \_ -> points
Right val -> return pts
Note that the \_ ->
bit ignores the first action's return value. So you can use the >>
operator, which does the same thing as >>=
, but throws away the first action's result:
points = do
pts <- try(readLn :: IO Int) :: IO (Either SomeException Int)
case pts of
Left ex -> putStrLn "Please enter a number." >> points
Right val -> return pts