我有密码
main :: IO()
main = runInputT defaultSettings loop
where
--loop :: InputT IO ()
loop = do
minput <- getInputLine "$ "
case minput of
Nothing -> return ()
Just input -> process $ words input
loop 其中,流程具有类型定义。
process :: [String] -> IO ()然而,我得到了错误:
• Couldn't match type ‘IO’ with ‘InputT m’
Expected type: InputT m ()
Actual type: IO ()
• In the expression: process $ words input
In a case alternative: Just input -> process $ words input
In a stmt of a 'do' block:
case minput of {
Nothing -> return ()
Just input -> process $ words input }我想知道是否有人能解释我做错了什么。我只想从getInputLine获得原始输入来做其他的事情。
谢谢
发布于 2016-12-07 10:43:18
do块中的所有语句都必须具有相同的类型(好的,它们的类型必须是相同的monad )。在您的例子中,这是InputT IO something ( monad是InputT IO)。
getInputLine "$ "有InputT IO (Maybe String)类型,所以这个部分没有问题。
然后有一个case表达式,这意味着所有分支都需要具有相同的类型。第一个分支就是return (),它获取InputT IO ()类型。目前为止一切都很好。
第二个分支是process $ words input。但这是IO ()类型,而不是InputT IO ()类型,这正是编译器目前所期望的。
要修复这个问题:幸运的是,有一种简单的方法可以将("lift")类型的值转换为IO x,即liftIO函数:
Just input -> liftIO (process $ words input)也就是说,liftIO :: IO a -> InputT IO a (实际上它比它更一般:liftIO :: (MonadIO m) => IO a -> m a,但这在这里并不重要)。
https://stackoverflow.com/questions/41015045
复制相似问题