readInputLine с IO String
Я хотел бы прочитать входную строку с пользовательской подсказкой, однако строка подсказки происходит из нечистого контекста, поэтому я не могу использовать readInputLine
как есть. Я пытался реализовать функцию, основанную на этом ответе
getLineIO :: MonadException m => IO String -> InputT m (Maybe String)
getLineIO ios = do
s <- ios
res <- getInputLine s
lift res
но я получаю ошибку
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 }
Обновление: заставил его работать на основе ответа@bheklilr
getLineIO :: (MonadException m, MonadIO m) => IO String -> InputT m (Maybe String)
getLineIO ios = do
s <- liftIO ios
getInputLine s
1 ответ
Код
do
s <- ios
res <- getInputLine s
lift res
Получает обезвоженный в
ios >>= \s -> (getInputLine s >>= \res -> lift res)
куда
(>>=) :: Monad m => m a -> (a -> m b) -> m b
Этот тип подписи означает, что m
должен быть таким же Monad
экземпляр во всем. Вы дали это ios :: IO String
а также \s -> getInputLine s :: String -> InputT n (Maybe String)
, но m
не может быть и то и другое IO
а также InputT n
отсюда ошибка компилятора.
Вы можете просто использовать liftIO
на ios
предоставлена instance MonadIO m => MonadIO (InputT m)
определяется, что это такое. Так что вы можете просто сделать
getLineIO :: (MonadException m) => IO String -> InputT m (Maybe String)
getLineIO ios = do
s <- liftIO ios
res <- getInputLine s
lift res