如何避免使用符号中的多余变量?

rid*_*ish 16 haskell do-notation

在Haskell do-notation块中说,我希望有一个变量来is_root指示我是否是root:

import System.Posix.User
main = do
    uid <- getRealUserID
    is_root <- return $ uid == 0
Run Code Online (Sandbox Code Playgroud)

那个讨厌的uid变量只用在那个地方.我希望我可以这样写:

main = do
    is_root <- getRealUserID == 0
Run Code Online (Sandbox Code Playgroud)

但当然不会编译.

我怎样才能摆脱多余的变量uid呢?这是我提出的最好的:

import System.Posix.User
main = do
    is_root <- getRealUserID >>= return . ((==) 0)
Run Code Online (Sandbox Code Playgroud)

布莱什!有更好的方法吗?

pdw*_*pdw 23

一种方法是

fmap (== 0) getRealUserID
Run Code Online (Sandbox Code Playgroud)

  • 注意`m >> = return.f`(如问题中的代码所示)必须等于`Monad`法则的`fmap fm`:http://hackage.haskell.org/package/base/docs/Control-Monad.html# T:单子 (8认同)
  • (<$>)也在Data.Functor中 (3认同)
  • @PeterHall`(<$>)`仍然是`Functor`实例中`fmap`的同义词,它经常与应用符号一起使用(并为此目的从`Control.Applicative`重新导出). (2认同)

Lam*_*eek 6

(我假设你的目标是限制范围uid,而不仅仅是为了它自己的缘故)

在这样一个简单的例子中,@ pdw的答案可能就是这样.操作员<$><*>来自Control.Applicative这里特别有帮助.

foo = do
  are_same <- (==) <$> doThis <*> doThat
Run Code Online (Sandbox Code Playgroud)

在稍微复杂的情况下,您可以使用嵌套 - do:

complicatedEq :: This -> That -> IO Bool

main = do
  are_same <- do
    this <- doThis
    that <- doThatBasedOn this
    complicatedEq this that
  ... rest ...
Run Code Online (Sandbox Code Playgroud)

任何显着长度的东西都可能是它自己的功能.