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ブロックです。3doブロック目までは大丈夫です。しかし、次の行で:

        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

エラーの原因は if式の誤用だと思います。ほとんどの命令型言語に存在するifステートメントのように使用します。簡単に言えば、常にelse.

ただし、do ブロックでは、else のない if ステートメントのような「else を持たない」ことは理にかなっています。幸いなことに、Control.Monadモジュールはまさにそのための機能を提供します。

import Control.Monad (when)

(...)

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

ネストされた do ブロックを正しい方法で既に使用しているようです。これは基本的に、適切にインデントする必要があるということです。

PS。また、コードの残りの部分と同様に、最後return ()がインデントされていることを確認してください! DS。

于 2012-12-04T01:29:24.403 に答える