Don按要求回答了这个问题,但一个稍微有趣的问题是如何处理
data Foo = Foo (MVar Bar) String
data Bar = Bar (MVar Foo) String
现在这两个 MVar 不仅仅是递归的旁观者,他们是同谋。
这可以通过两种方式完成:
1.) 要么做你会用 C 之类的命令式语言做的事情:
mutation = do
-- setting up an empty mvar
bar <- newEmptyMVar
foo <- newMVar (Foo bar "foo")
-- and then filling it in
putMVar bar (Bar foo "foo")
return (foo, bar)
2.) 或使用 DoRec(以前称为 RecursiveDo)和 mfix 并在幕后喜结连理:
{-# LANGUAGE DoRec #-}
mutual = do
rec foo <- newMVar (Foo bar "foo")
bar <- newMVar (Bar foo "foo")
return (foo, bar)
这转化为类似于:
mutual = do
(foo, bar) <- mfix $ \(foo, bar) -> do
foo <- newMVar (Foo bar "foo")
bar <- newMVar (Bar foo "foo")
return (foo, bar)
return (foo, bar)