I have the code
main :: IO()
main = runInputT defaultSettings loop
where
--loop :: InputT IO ()
loop = do
minput <- getInputLine "$ "
case minput of
Nothing -> return ()
Just input -> process $ words input
loop
Where process has the type definition
process :: [String] -> IO ()
However I get the error:
• Couldn't match type ‘IO’ with ‘InputT m’
Expected type: InputT m ()
Actual type: IO ()
• In the expression: process $ words input
In a case alternative: Just input -> process $ words input
In a stmt of a 'do' block:
case minput of {
Nothing -> return ()
Just input -> process $ words input }
I was wondering if anybody could explain what I'm doing wrong. I just want to raw input from getInputLine to do other things with.
Thanks
All statements in a
doblock must have the same type (well, must have the same monad in their type). In your case, this isInputT IO something(with the monad beingInputT IO).getInputLine "$ "has typeInputT IO (Maybe String), so that part is OK.Then you have a
caseexpression, which means all branches need to have the same type. The first branch is justreturn (), which gets the typeInputT IO (). All good so far.The second branch is
process $ words input. But this has typeIO (), notInputT IO (), which is what the compiler expects at this point.To fix this: Fortunately there's an easy way to convert ("lift") a value of type
IO xtoInputT IO x, which is theliftIOfunction:That is,
liftIO :: IO a -> InputT IO a(actually it's more general than that:liftIO :: (MonadIO m) => IO a -> m abut that doesn't matter here).