5

我正在尝试在 Haskell 中编写一个函数来检查一些东西,然后根据一些最小的用户输入进行递归。为了做到这一点,我认为我必须使用do块。

cip :: [Argument] -> [Argument] -> Bool -> Bool -> IO()
cip (a:args) pargs burden gameover = do
    let nasko = a:pargs
    putStrLn (getPremise a)
    let newgraph = Carneades.mkArgGraph nasko
    let newcaes = (CAES (newgraph,audience2,assStandarts)) 
    let answer = (acceptable (mkProp (getPremise a)) newcaes )
    print answer
    if(answer==True) 
    then (cip args nasko burden gameover) 
    else do
        print "One of the arguments is not proved. Here are the premises that need proving"
        print (propsForFixing newcaes a)
        print "Let's see what you have for the first Propositon"
        --add an if to check if no applicable arguments.
        print (argumentScanHelp (head (propsForFixing newcaes a)) args)
        print "\n Would you like me to apply the firt one? Y/N"
        choice <- getLine
        if(choice=="Y") then do print "applying the argument"
                                let applicabee = head (argumentScanHelp (head (propsForFixing newcaes a)) args)
                                print "Argument targeted"
                                let newargs = delete applicabee args
                                let newpargs = applicabee:nasko
                                print "Argument applied sucsessfuly. Recusing again"
                                (cip newargs newpargs burden gameover)
return()

只是看着它就伤害了我的眼睛,但这do对你来说是障碍。直到第三个do街区的一切都很好。但随后在这一行:

        if(choice=="Y") then do print "applying the argument"
                                let applicabee = head (argumentScanHelp (head (propsForFixing newcaes a)) args)

编译器开始哭泣:

Main.hs:209:73: parse error on input `let'

尝试了各种不同的缩进,但我似乎无法让它工作。我不想使用单独的函数,因为这意味着我必须不断地传递很多参数。

任何人都可以帮我做对吗?do还非常感谢解释嵌套块的具体规范是什么。

4

1 回答 1

10

The cause of the error I believe is the misuse of the if expression. You use it as if it were an if statement that exists in most imperative languages. Simply put there must always be an else.

However, in do blocks it makes sense to "not have an else", something like an if statement without an else. Luckily the Control.Monad module will provide you with a function for exactly that:

import Control.Monad (when)

(...)

when (choice=="Y") $ do print "applying the argument"
                        let applicabee = ...

You seem to already use nested do blocks in the correct way which is good, which basically is that you must indent properly.

PS. Also make sure your last return () is indented like the rest of your code! DS.

于 2012-12-04T01:29:24.403 回答