带有 IO 字符串的 readInputLine
readInputLine with IO String
我想读取带有自定义提示的输入字符串,但是提示字符串来自不纯的上下文,因此我不能按原样使用 readInputLine
。我试图实现一个基于 this answer
的函数
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
代码
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
,因此编译器错误。
只要定义了 instance MonadIO m => MonadIO (InputT m)
,您就可以在 ios
上使用 liftIO
,确实如此。所以你可以做
getLineIO :: (MonadException m) => IO String -> InputT m (Maybe String)
getLineIO ios = do
s <- liftIO ios
res <- getInputLine s
lift res
我想读取带有自定义提示的输入字符串,但是提示字符串来自不纯的上下文,因此我不能按原样使用 readInputLine
。我试图实现一个基于 this answer
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
代码
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
,因此编译器错误。
只要定义了 instance MonadIO m => MonadIO (InputT m)
,您就可以在 ios
上使用 liftIO
,确实如此。所以你可以做
getLineIO :: (MonadException m) => IO String -> InputT m (Maybe String)
getLineIO ios = do
s <- liftIO ios
res <- getInputLine s
lift res