Haskell 带有IO字符串的readInputLine

Haskell 带有IO字符串的readInputLine,haskell,monads,monad-transformers,haskeline,Haskell,Monads,Monad Transformers,Haskeline,我想用自定义提示读取输入字符串,但是提示字符串来自不纯的上下文,因此我不能按原样使用readInputLine。我试图实现一个基于 getLineIO::MonadException m=>IO字符串->输入m(可能是字符串) getLineIO ios=do s IO字符串->输入m(可能是字符串) getLineIO ios=do s代码 do s <- ios res <- getInputLine s lift res 在哪里 此类型签名意味着m必须

我想用自定义提示读取输入字符串,但是提示字符串来自不纯的上下文,因此我不能按原样使用
readInputLine
。我试图实现一个基于

getLineIO::MonadException m=>IO字符串->输入m(可能是字符串)
getLineIO ios=do
s IO字符串->输入m(可能是字符串)
getLineIO ios=do
s代码

do
    s <- ios
    res <- getInputLine s
    lift res
在哪里

此类型签名意味着
m
必须始终是相同的
Monad
实例。您已经给了它
ios::IO String
\s->getInputLines::String->input n(可能是String)
,但是
m
不能同时是
IO
input n
,因此编译器错误

只要定义了实例MonadIO m=>MonadIO(input m)
,就可以在
ios
上使用
liftIO
。所以你可以这么做

getLineIO :: (MonadException m) => IO String -> InputT m (Maybe String)
getLineIO ios = do
    s <- liftIO ios
    res <- getInputLine s
    lift res
getLineIO::(MonadException m)=>IO字符串->输入m(可能是字符串)
getLineIO ios=do
s代码

do
    s <- ios
    res <- getInputLine s
    lift res
在哪里

此类型签名意味着
m
必须始终是相同的
Monad
实例。您已经给了它
ios::IO String
\s->getInputLines::String->input n(可能是String)
,但是
m
不能同时是
IO
input n
,因此编译器错误

只要定义了实例MonadIO m=>MonadIO(input m)
,就可以在
ios
上使用
liftIO
。所以你可以这么做

getLineIO :: (MonadException m) => IO String -> InputT m (Maybe String)
getLineIO ios = do
    s <- liftIO ios
    res <- getInputLine s
    lift res
getLineIO::(MonadException m)=>IO字符串->输入m(可能是字符串)
getLineIO ios=do

s您可能只需要使用
lift
IO字符串
转换为
Input IO字符串
,即
s您可能只需要使用
lift
IO字符串
转换为
Input IO字符串
,即
s谢谢,您是否同时对
MonadException
MonadIO
使用
m
?@dimid
liftIO
要求您所在的
Monad
也实现
MonadIO
。查看后,似乎
MonadException
已经需要
MonadIO
,因此您可以放弃该要求。但是,如果您在不同的
Monad
中工作,则可能对特定的
m
有多个约束。看到基于
mtl
的代码带有
(MonadState s m、MonadWriter w m、MonadIO m)=>…
谢谢,您是否同时对
MonadException
MonadIO
使用
m
?@dimid
liftIO
要求您所在的
Monad
也实现
MonadIO
。查看后,似乎
MonadException
已经需要
MonadIO
,因此您可以放弃该要求。但是,如果您在不同的
Monad
中工作,则可能对特定的
m
有多个约束。看到基于
mtl
的代码具有
(MonadState s m、MonadWriter w m、MonadIO m)=>…
ios >>= \s -> (getInputLine s >>= \res -> lift res)
(>>=) :: Monad m => m a -> (a -> m b) -> m b
getLineIO :: (MonadException m) => IO String -> InputT m (Maybe String)
getLineIO ios = do
    s <- liftIO ios
    res <- getInputLine s
    lift res