私は次のような苦境に苦しんでいます。IO以外の環境でIOアクションを実行する
evalAExpr :: AExpr -> Env -> Int
evalAExpr (Var x) env = actAccordingly (getValueOfBinding env x)
where
actAccordingly (Left int) = int
actAccordingly (Right stmt) = eval stmt env
eval :: Stmt -> Env -> IO Env`
getValueOfBinding :: Env -> String -> Either Integer Stmt
だから何が起こる必要があることはどちらのモナドから得のstmt x
と、それは新しい環境に(理由は他のプロセスと、IO
で発生する必要がある)x
を評価すべきであるということである、後の私は環境から正しい値を返すことができます。しかし、ハスケルの私の限られた知識から、私はIO
から出ることはできません。
例:は、すべてevalAExpr
が機能しているので(現在1つ以上あります)、Env atmを返すため、現在のコードでは動作しません。これを変更しなければならない場合は、評価do文とreturn文をすべて追加することになります。 > 50〜60回の発生。確かに。そうすれば、コードを見るのが面倒になるでしょう。私がIOを必要とするのは、この評価が(ある時点で)mBot(http://makeblock.com/mbot-stem-educational-robot-kit-for-kids/)からデータを収集するだけでなく、キーボードからデータを収集する必要があるからです(getLine経由で完了)。
私はそれを整然とし、整理しておくことができるようにこのコードを再加工する方法?
もっとコードが必要な場合は、気軽にping/mentionをしてください。私は要求されたコード行を提供します。要求されたよう
もっとコード:EvalAExprが使用されている方法を示し
- コード。に - 唯一の重要な変更が本当にあり
evalAExprIO :: AExpr -> Env -> IO Int evalAExpr (Var x) env = actAccordingly (getValueOfBinding env x) where actAccordingly (Left int) = return int actAccordingly (Right stmt) = eval stmt env
:あなたは私たちは、新しいバージョン
evalAExprIO
と呼ぶことにしますevalAExpr
のモナドバージョンを記述する必要が
-- Relational operators evalBExpr (RBinary Greater a b) env = evalAExpr a env > evalAExpr b env evalBExpr (RBinary Less a b) env = evalAExpr a env < evalAExpr b env evalBExpr (RBinary Equal a b) env = evalAExpr a env == evalAExpr b env
関数がIOを実行する場合は、IOタイプを返す必要があります。それ以外の場合、関数は副作用がないと見なしています。もしこれが嘘であれば、コンパイラはそれを見つけます。これを回避するには合理的な方法はありませんが、IOを実行する機能のタイプにIOを追加することはできません。 – chi
おそらく、評価ルーチンでIOを使用する必要がある理由を説明する必要があります。選択肢があるかもしれません... – ErikR
あなたの言語の例を挙げてください。通常のPython/Javascriptのような命令的な言語ですか? – ErikR