I would like to combine the Error Monad and the IO Monad in Haskell. Here is an excerpt from my code:
type AskMonad = ErrorT String IO
askSomething :: AskMonad Direction
askSomething = do
liftIO $ putStrLn "Choose an element from the list [1,2,3,4]"
input <- liftIO getLine
let entry = read input :: Int
if entry `elem` [1,2,3,4]
then return $ toEnum entry -- from Int to Direction
else throwError "Invalid input!"
selectMove :: [Player] -> Board -> IO (Direction, Position)
selectMove players board = do
direction <- runErrorT (askSomething) `catchError` --What to put here???
-- Other IO stuff...
I would like to achieve the following behavior:
- if
askSomething
succeeds, get theDirection
. - if
askSomething
fails,show
the error and runaskSomething
again.
However, I don't know what to put as the second argument of catchError
in order to get this behavior. I think it should be of the following type signature: Either String Direction -> AskMonad Direction
, but how can I access the computation that needs to be rerun (askSomething
in this case).