有没有办法在if语句中使用IO Bool而不绑定haskell中的名称?

Dax*_*ohl 14 monads haskell

如果我有一个返回的函数IO Bool(特别是一个atomically),有没有办法直接在if语句中使用返回值,而不绑定?

所以目前我已经有了

ok <- atomically $ do
  ...
if (ok) then do
  ...
else do
  ...
Run Code Online (Sandbox Code Playgroud)

是不是可以把它写成类似的东西

if (*some_operator_here* atomically $ do
      ...) then do
  ...
else do
  ...
Run Code Online (Sandbox Code Playgroud)

我希望有一种方法可以使用<-匿名的东西,即,if (<- atomically ...)但到目前为止还没有这样的运气.

类似地,在getLine上,是否可以编写类似的内容

if ((*operator* getLine) == "1234") then do ...
Run Code Online (Sandbox Code Playgroud)

相关附录 - 是什么类型的(<-)?我无法让它出现在ghci中.我假设它是m a -> a,但那意味着它可以在monad之外使用来逃避那个不安全的monad,对吧?是(<-)不是一个功能呢?

Sat*_*vik 16

您可以使用ifMControl.Conditional是否适合你的目的和它甚至并不难写一个类似的功能.

只是举个例子

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")
Run Code Online (Sandbox Code Playgroud)

我认为有一些方法可以使用可重新绑定的语法扩展,你甚至可以if c then e1 else e2像语法一样使用ifM它,但是不值得努力尝试.


Joa*_*ner 6

使用 GHC 7.6 和LambdaCase语言扩展,您可以编写

{-# LANGUAGE LambdaCase #-}

导入 System.Directory

主要 = 做
    doFileExist "/etc/passwd" >>= \case
        真 -> putStrLn "是"
        假 -> putStrLn "否"

它不完全是if..then..else,但足够接近,不需要绑定到结果,并且有些人(不是我)说if..then..else无论如何在 Haskell 中这是糟糕的风格。