I would like to read an input string with a custom prompt, however the prompt string comes from impure context, thus I can't use readInputLine
as is. I've tried to implement a function based on this answer
getLineIO :: MonadException m => IO String -> InputT m (Maybe String)
getLineIO ios = do
s <- ios
res <- getInputLine s
lift res
but I get an error
Couldn't match expected type ‘InputT m String’
with actual type ‘IO String’
Relevant bindings include
getLineIO :: IO String -> InputT m (Maybe String)
(bound at Main.hs:38:1)
In a stmt of a 'do' block: s <- ios
In the expression:
do { s <- ios;
return $ getInputLine s }
Update: got it to work based on @bheklilr's answer
getLineIO :: (MonadException m, MonadIO m) => IO String -> InputT m (Maybe String)
getLineIO ios = do
s <- liftIO ios
getInputLine s
The code
Gets de-sugared into
Where
This type signature means that
m
has to be the sameMonad
instance throughout. You've given itios :: IO String
and\s -> getInputLine s :: String -> InputT n (Maybe String)
, butm
can't be bothIO
andInputT n
, hence the compiler error.You can just use
liftIO
onios
providedinstance MonadIO m => MonadIO (InputT m)
is defined, which it is. So you can just do