Particularly, I need to be able to combine the CGI monad with the IO monad, but an example of how to combine the IO monad with the Maybe monad might be even better...
问问题
5951 次
3 回答
22
我假设您想使用 Maybe monad 提前终止(如break
或return
在 C 中)。
在这种情况下,您应该使用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 是 Maybe monad 的 monad 转换器版本。
Monad 转换器“添加功能”到其他 monad。
于 2009-07-14T20:06:22.830 回答
17
您并没有确切说明您想如何组合IO
and 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
-Notation 来组合返回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 结合起来的程度。
于 2009-07-14T18:49:27.290 回答
0
你想在什么意义上结合单子?
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
于 2009-07-14T16:57:24.643 回答