我有来自互联网的以下代码段:
calculateLength :: LengthMonad Int
calculateLength = do
-- all the IO operations have to be lifted to the IO monad in the monad stack
liftIO $ putStrLn "Please enter a non-empty string: "
s <- liftIO getLine
if null s
then throwError "The string was empty!"
else return $ length s
又不明白,为什么作者使用liftIO
?
目的是liftIO
什么?
定义如下:
class (Monad m) => MonadIO m where
-- | Lift a computation from the 'IO' monad.
liftIO :: IO a -> m a
可以举起IO a -> [a]
吗?看起来像是自然的转变。
IO
像getLine, putStrLn "..."
仅在IO
monad内部运行的操作。在其他任何monad中使用它们将触发类型错误。
仍然有许多monadM
的定义IO
(例如StateT Int IO
和,显然也是您LengthMonad
定义的),因此,它们允许将IO
动作转换为M
-actions并如此执行。
但是,我们需要为每个转换M
:
convertIOintoM1 :: IO a -> M1 a
convertIOintoM2 :: IO a -> M2 a
convertIOintoM3 :: IO a -> M3 a
...
由于这很麻烦,因此该库定义了MonadIO
具有此类转换功能的类型类,因此可以liftIO
改为命名上述所有功能。
在实践中,liftIO
每次有人想IO
在另一个monad中运行操作时都使用,只要这种monad允许这样做。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句