我从getInputline
获得了一个结果,其类型为:
(MonadException m) => IO String -> InputT m (Maybe String)
我想获得Maybe String
部分。我很清楚,正如this answer(以及同一问题中的其他答案)中所解释的那样,一般情况下无法剥离monad。但是,由于我在InputT
内进行此操作,我认为这是可能的,正如提议here一样。但是,正如答案所示,我无法使用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