2017-11-16 14 views
1

私は最初にオブジェクトを作成するコードをいくつか持っています。次に、さまざまなコマンドに応じてオブジェクトのさまざまな更新を実行したいと思います。haskellのif文で作成されたIO/access変数の変数を更新する方法

main = do 
    putStrLn "Enter command, c x y, d x y" 
    s <- getLine 
    let object = newObject 
    if head s == 'c' then 
     let object2 = updateObject object s in 
     print object 
    else if head s == 'd' then 
     let object2 = updateObject object s in 
     print object 
    else do 
     print "Error, try again" 
     main 
    putStrLn "Enter new command" 
    c <- getLine 
    print $ updateObject object2 c 

エラー:

Variable not in scope: object2 :: Object 

文は、後で使用することができた場合、変更は内部のオブジェクトに行われるように、私は主な機能のためのオブジェクトは、「グローバル」にするにはどうすればよいですか?

どうすればいいですか?

+4

はちょうどobject2は返す関数を作成します。とにかく、あなたはなぜか、そして、とにかく、両方のパスが同じコードを実行しています – Glubus

+0

ありがとう!彼らはコードが完了したときに別のものになっているはずです。 オブジェクト2を返す関数を作ってどういう意味ですか?関数updateObjectはobject2を返しますが、別のパラメータで異なる時刻に実行します。私はいくつかの異なるifを別々のアップデートで持っています。どのようにすれば、すべての更新で最終的なオブジェクトにアクセスできますか? –

+0

'let object2 = updateObjectオブジェクトs in'は、' in'の後の式のために 'object2'を定義します。あなたは外でそれを使用しようとしています。 Henseコンパイラエラー。 – d12frosted

答えて

2

メインではあまりおこなわないようにしてください。ifとelseロジックが存在してはいけません。すべてのものを別の機能に移動し、メインをきれいにしてください。 ここで使用するifとelseのロジックは、ドメイン選択ではなく、アプリケーションのフローに直接関係しているので有効です(domain =この関数またはこの関数を使って更新する必要がありますか?私のプログラムのために、私は終了するかしないか)。

main = do 
     putStrLn "Enter command, c x y, d x y" 
     s <- getLine 
     if not $ validateInput s then 
      print "Error, try again" 
      main 
     else do 
      let object = newObject 
      updateObject object s 
      print object 


updateObject :: a -> String -> a 
updateObject object s 
      | head s == 'c' = --do updates here 
      | head s == 's' = --do updates here 

また、あなたが簡単な状況「新しいコマンドを入力します」を扱うことができるように、コンソールのループを作成しよう:

はこれを試してみてください。できるだけ早くメインから離れる。

+1

ここで 'head'を使うのは貧弱です。 's'が空の文字列なら何ですか? – chepner

+0

@Glubusありがとう!私はあなたがここに書いているものに基づいてそれを修正する方法について考えていると思う。 –

+0

@chepner sが 's'または 'c'で始まらない場合はどうすればいいですか?これは懸念の分離を強調する単なる例です。updateObjectは堅牢な関数ではありません。つまり、4行目のvalidateInputは、このプログラムの安定性を暗示すべきです(別の場所ではクラッシュ可能なコードを書かないという言い訳ではありません)。 – Glubus

1

Object -> Object、モナドStateIORefなどのような機能があります。どのようにするかは、正確に何をしたいかによって異なります。

最も簡単な方法(初心者の方)は、オブジェクトの更新バージョンを生成する関数によってこれを行うのが最も簡単です。例えば

updateObject :: Command -> Object -> Maybe Object 
updateObject command initialObject = case command of 
    'c':_ -> Just $ ... -- update initialObject by the 'c' command 
    'd':_ -> Just $ ... -- update initialObject by the 'd' command 
    _  -> Nothing -- invalid command 

main = do 
    putStrLn "Enter command, c x y, d x y" 
    command <- getLine 
    case updateObject command newObject of 
     Just updatedObject -> print updatedObject 
     Nothing -> do 
      print "Error, try again" 
      main 
関連する問題