来自 Reader monad 的 Sugaring monadic 代码

Sugaring monadic code from Reader monad

我使用 reader monad 编写了一些 monadic 代码,我想知道是否有任何方法可以使用 do-notation 来编写:

m = Map.fromList [("This","is"), ("is","the"), ("the","secret")]
f x m = fromMaybe "default" $ Map.lookup x m

r :: String -> Reader (Map String String) String)
r x = reader $ \m1 -> f x m1

runReader ((r "This") >>= r >>= r) m
-- "secret"

现在你会如何用 do 表示法写最后一个语句。

我感觉所有使用 runX 函数的 "expanded monads" 都不太适合 do-notation。

do-notation 只是:

runReader r' m
    where r' = do
        x <- r "This"
        y <- r x
        z <- r y
        return z

但使用 (>>=) 更有意义。

你可以

runReader threeRs m where
  threeRs = do
   a <- r "This"
   b <- r a
   r b

虽然我不推荐这个。在这种情况下,使用绑定 (>>=) 运算符非常适合实际链接。

恕我直言,do 符号在对不需要所有结果的单子操作进行排序时最有用,应该组合结果,或者在两者之间使用纯函数。另见 Should do-notation be avoided in Haskell?