如果我有一个返回IO Bool
的函数(特别是atomically
),有没有办法直接在if
语句中使用返回值,而不绑定?< / p>
所以目前我已经
了ok <- atomically $ do
...
if (ok) then do
...
else do
...
是否可以将其写为
之类的内容if (*some_operator_here* atomically $ do
...) then do
...
else do
...
我希望有一种方法可以匿名使用<-
之类的东西,即if (<- atomically ...)
,但到目前为止还没有这样的运气。
同样在getLine上,是否可以编写类似
的内容if ((*operator* getLine) == "1234") then do ...
相关附录 - (<-)
的类型是什么?我无法让它出现在ghci中。我假设它是m a -> a
,但那意味着它可以在monad之外使用来逃避那个不安全的monad,对吧? (<-)
根本不是一个功能吗?
答案 0 :(得分:16)
如果符合您的目的,您可以使用Control.Conditional
中的ifM
,甚至难以编写类似的功能。
只是举个例子
import Control.Conditional
import Control.Monad
(==:) :: ( Eq a,Monad m) => m a -> m a -> m Bool
(==:) = liftM2 (==)
main = ifM (getLine ==: getLine) (print "hit") (print "miss")
我认为有一些方法可以使用可重新绑定的语法扩展,你甚至可以使用if c then e1 else e2
类ifM
的语法,但是不值得努力尝试。
答案 1 :(得分:4)
使用GHC 7.6和LambdaCase
语言扩展,您可以编写
{-# LANGUAGE LambdaCase #-} import System.Directory main = do doesFileExist "/etc/passwd" >>= \case True -> putStrLn "Yes" False -> putStrLn "No"
它不完全是if..then..else
,但更接近,不需要绑定到结果,而且有些人(不是我)说H if..then..else
在Haskell中是不好的风格。
答案 2 :(得分:1)
为什么这不可能?嗯,首先,类型IO Bool
的值在任何意义上都不包含类型Bool
的值。相反,它是一个“动作”,执行时将返回类型Bool
的值。另一方面,如果这是可能的,它将允许你隐藏在看似纯粹的代码的副作用。这将违反Haskell的核心原则。 Haskell非常有原则。