Как избежать лишних переменных в обозначении?

Скажите в блоке do-notation Haskell, я хочу иметь переменную is_root, указывающую, является ли я root:

import System.Posix.User
main = do
    uid <- getRealUserID
    is_root <- return $ uid == 0

Эта раздражающая переменная uid используется только в одном месте. Вместо этого я могу написать следующее:

main = do
    is_root <- getRealUserID == 0

Но, конечно, это не скомпилируется.

Как я могу избавиться от лишних переменных, таких как uid? Здесь лучшее, что я придумал:

import System.Posix.User
main = do
    is_root <- getRealUserID >>= return . ((==) 0)

Blech! Есть ли лучший способ?

Ответы

Ответ 1

Один из способов -

fmap (== 0) getRealUserID

Ответ 2

(Я предполагаю, что ваша цель - ограничить область uid, а не просто быть свободным ради себя)

В простом случае, @pdw answer, вероятно, это путь. Операторы <$> и <*> из Control.Applicative особенно полезны здесь.

foo = do
  are_same <- (==) <$> doThis <*> doThat

В несколько более сложных ситуациях вы можете использовать inested- do:

complicatedEq :: This -> That -> IO Bool

main = do
  are_same <- do
    this <- doThis
    that <- doThatBasedOn this
    complicatedEq this that
  ... rest ...

Все, что значительно долго, вероятно, заслуживает своей собственной функции.