[英]How do I combine monads in Haskell?
特别是,我需要能够将CGI monad与IO monad结合起来,但是如何将IO monad与Maybe monad相结合的示例可能会更好......
我假设你想使用Maybe monad提前终止(比如在C中break
或return
)。
在这种情况下,你应该使用MaybeT
从MaybeT包( cabal install MaybeT
)。
main = do
runMaybeT . forever $ do
liftIO $ putStrLn "I won't stop until you type pretty please"
line <- liftIO getLine
when ("pretty please" == line) mzero
return ()
MaybeT是monad的monad变换器版本。
Monad变形金刚“为其他monad添加功能”。
你没有确切地说你想要如何组合IO
和Maybe
,但是我假设你有许多函数可以返回你想要轻松组合的IO (Maybe a)
。 基本上你想把IO (Maybe a)
作为一个独立的类型用它自己的Monad
实例来对待:
newtype IOMaybe a = IOM (IO (Maybe a))
-- "unpack" a value of the new type
runIOMaybe :: IOMaybe a -> IO (Maybe a)
runIOMaybe (IOM a) = a
instance Monad IOMaybe where
-- bind operator
(IOM ioa) >>= f = IOM $ do
a <- ioa
case a of
Nothing -> return Nothing
Just v -> runIOMaybe (f v)
-- return
return a = IOM (return (Just a))
-- maybe also some convenience functions
returnIO :: IO a -> IOMaybe a
returnIO ioa = IOM $ do
v <- ioa
return (Just v)
returnMaybe :: Maybe a -> IOMaybe a
returnMaybe ma = IOM (return ma)
有了这个,您可以使用do
-otation来组合返回IO (Maybe a)
, IO a
或者Maybe a
函数:
f1 :: Int -> IO (Maybe Int)
f1 0 = return Nothing
f1 a = return (Just a)
main = runIOMaybe $ do
returnIO $ putStrLn "Hello"
a <- returnMaybe $ Just 2
IOM $ f1 a
return ()
通常,组合和修改这样的monad的东西称为monad变换器 ,GHC附带一个包含monad变换器的包 ,用于常见情况。 如果此monad变换器库中有适合您的场景的内容取决于您希望如何组合Maybe和IO。
在什么意义上你想组合monad?
f :: Int -> IO (Maybe Int)
f x = do
putStrLn "Hello world!"
return $ if x == 0 then Nothing else Just x
可以评估为:
[1 of 1] Compiling Main ( maybe-io.hs, interpreted )
Ok, modules loaded: Main.
*Main> f 0
Hello world!
Nothing
*Main> f 3
Hello world!
Just 3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.