Haskell 如何避免do符号中的多余变量?
假设在Haskell do符号块中,我希望有一个变量Haskell 如何避免do符号中的多余变量?,haskell,do-notation,Haskell,Do Notation,假设在Haskell do符号块中,我希望有一个变量is_root指示我是否为root: import System.Posix.User main = do uid <- getRealUserID is_root <- return $ uid == 0 但这当然不会编译 如何去除多余的变量,如uid?以下是我想到的最好的: import System.Posix.User main = do is_root <- getRealUserID &g
is_root
指示我是否为root:
import System.Posix.User
main = do
uid <- getRealUserID
is_root <- return $ uid == 0
但这当然不会编译
如何去除多余的变量,如uid
?以下是我想到的最好的:
import System.Posix.User
main = do
is_root <- getRealUserID >>= return . ((==) 0)
import System.Posix.User
main=do
is_root>=返回。((==) 0)
哎哟!有更好的方法吗?一种方法是
fmap (== 0) getRealUserID
(我假设您的目标是限制uid
的范围,而不仅仅是为了它本身的目的而无点限制)
在这样一个简单的情况下,这可能是一条可行的道路。来自控件的操作符
和
在这里特别有用
foo = do
are_same <- (==) <$> doThis <*> doThat
任何长得很长的函数都应该是它自己的函数。注意m>>=return。根据Monad
定律,f
(与问题中的代码一样)必须等于fmap fm
:您也可以使用应用程序实例,例如:is_root@PeterHall()
仍然是Functor
实例中fmap
的同义词,它经常与应用程序符号一起使用(并为此目的从Control.applicative
重新导出)。()也在Data.Functor中。当计算在IO
上下文中运行时(通过适当的导入)Functor
,applicative
当然还有Monad
实例确实存在,您可以随意应用任何映射函数。这并不能消除额外的变量,但您还应该使用let is_root=uid==0
而不是is_root我看不出您的尝试有什么不好的地方,只要在bind的正确操作数中,它可能会缩短为return。(==0)
。
foo = do
are_same <- (==) <$> doThis <*> doThat
complicatedEq :: This -> That -> IO Bool
main = do
are_same <- do
this <- doThis
that <- doThatBasedOn this
complicatedEq this that
... rest ...