Haskell中嵌套的`do`块

Ata*_*kov 4 haskell

我正在尝试在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()
Run Code Online (Sandbox Code Playgroud)

只是通过观察它会伤到我的眼睛,但这do对你来说是块状的.到第三个do区块的一切都没问题.但是在这一行:

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

编者开始哭泣:

Main.hs:209:73: parse error on input `let'
Run Code Online (Sandbox Code Playgroud)

尝试了各种不同的缩进,但我似乎无法让它工作.我不想使用单独的函数,因为这意味着我将不得不经常传递很多论点.

任何人都可以帮助我做对吗?do还将非常感谢对嵌套块的确切规范的解释.

Tar*_*sch 9

我认为错误的原因是滥用if 表达式.您可以像使用大多数命令式语言中存在的if 语句一样使用它.简单地说,必须始终有一个else.

然而,在do块中,"没有其他"是有意义的,类似于没有else的if语句.幸运的是,该Control.Monad模块将为您提供以下功能:

import Control.Monad (when)

(...)

when (choice=="Y") $ do print "applying the argument"
                        let applicabee = ...
Run Code Online (Sandbox Code Playgroud)

您似乎已经以正确的方式使用嵌套的do块,这很好,这基本上是您必须正确缩进.

PS.还要确保你的最后一个return ()像其他代码一样缩进!DS.