Развернуть результат getInputLine из ввода
Я получаю результат от getInputline
тип которого:
(MonadException m) => IO String -> InputT m (Maybe String)
Я хотел бы получить только Maybe String
часть. Я хорошо знаю, что в общем случае нет способа раздеть монаду, как объясняется в этом ответе (и других ответах на тот же вопрос). Тем не менее, так как я делаю это внутри InputT
Я думаю, это возможно, как здесь предлагается. Тем не менее, я не могу просто использовать liftIO
Как следует из ответа, так как IO
находится внутри StateT
,
loop :: Counter -> InputT (StateT [String] IO) ()
loop c = do
minput <- getLineIO $ in_ps1 $ c
case minput of
Nothing -> outputStrLn "Goodbye."
Just input -> (process' c input) >> loop c
getLineIO :: (MonadException m) => IO String -> InputT m (Maybe String)
getLineIO ios = do
s <- liftIO ios
getInputLine s
process' :: Counter -> String -> InputT (StateT [String] IO) ()
[...]
Ошибка, которую я получаю:
Main.hs:81:15:
No instance for (MonadException (StateT [String] IO))
arising from a use of ‘getLineIO’
In the expression: getLineIO
In a stmt of a 'do' block: minput <- getLineIO $ in_ps1 $ c
In the expression:
do { minput <- getLineIO $ in_ps1 $ c;
case minput of {
Nothing -> outputStrLn "Goodbye."
Just input -> (process' c input) >> loop c } }
Если я удалю getLineIO
и использовать getInputLine
прямо по совету @chepner:
loop :: Counter -> InputT (StateT [String] IO) ()
loop c = do
minput <- (in_ps1 c) >>= getInputLine
case minput of
Nothing -> outputStrLn "Goodbye."
Just input -> (process' c input) >> loop c
Я получаю сообщение об ошибке:
Main.hs:81:16:
Couldn't match type ‘IO’ with ‘InputT (StateT [String] IO)’
Expected type: InputT (StateT [String] IO) String
Actual type: IO String
In the first argument of ‘(>>=)’, namely ‘(in_ps1 c)’
In a stmt of a 'do' block: minput <- (in_ps1 c) >>= getInputLine
Полный код можно найти здесь, а объяснения о том, что я пытаюсь сделать, можно найти здесь.