あなたは数字に変数名をマッピングした環境を維持する必要があります。
add :: Expr -> Expr
add expr = fst $ addWithEnv emptyEnv expr
where
emptyEnv = []
addWithEnv env (And e1 e2)
= case addWithEnv env e1 of
(e1', env') ->
case addWithEnv env' e2 of
(e2', env'') -> (And e1' e2', env'')
addWithEnv env (Var name)
= case lookup name env of
Just k -> -- stopping here,it's homework
ような何か私はあなたが記入するために、私は十分に残してきた期待し
更新:あなたの試みで
、あなたはすでに見てきたどの変数を追跡していません、すべての変数が最初のように見え、毎回 '1'が追加されます。ナンバリング項目はステートフルな計算です。以前に見た変数に以前の番号を割り当て、次に見られない変数を割り当てる番号を知るためには、どの変数がこれまでに見られたのかの記録を持たなければなりません。だからあなたはその記録を労働者の周りに運ばなければならない。もしあなたがすでにMonad
クラスについて知っていて、それを使う方法があれば、State
モナドを使ってそれを暗黙に持ち歩くことができます。それ以外の場合は明示的に持ち歩かなければなりません。その後、add
は、最初に空の状態(番号/名前の変更が始まる前に、変数はまだ見られません)で作業者を呼び出すラッパーになります。その後、ワーカーは指定された式のサブ式を調べ、変数の名前を変更し、新しい変数に遭遇したときの状態を更新します。
は、したがって、上記のスケッチでは、我々は
addWithEnv :: [(String,Int)] -> Expr -> (Expr, [(String,Int)])
を持って、我々は状態を変異させることができないので、私たちは、名前を変更した表現と一緒に新しい状態を返すことがあります。今、あなたは
addWithEnv env T = ??
addWithEnv env (Var name) = ??
addWithEnv env (Add e1 e2) = ??
addWithEnv env (Not e) = ??
もちろんのT
場合には名前の変更を行わず、環境を更新しない、結果は式の種類ごとにしなければならないかを定義する必要があります。 A Var
が以前に見られたかのいずれかであり、その場合、環境は変更されないままであり、そうでない場合、環境に追加される。 Not e
は、環境への影響が同じで、環境に及ぼす影響は最初にe1
、次にe2
となり、e
となり、And e1 e2
は、最初にe1
となる組み合わせ効果があります。
あなたは何をしようとしているのか、あなたの現在の解決策は何か、あなたはそれについて気に入らないものについて少し詳しく説明できますか? – leftaroundabout
変数に割り当てられた数字を除いて、入力に与えられているのとほぼ同じ式を出力しようとしています。私の現在のソリューション - Varに遭遇すると、変数をリストに追加し、そのリストを取る別の関数を呼び出し、そのリストの長さだけを変数の最後に追加する関数を呼び出します。リストが成長するにつれて私の理論は成長しますが、これは必然的に単なる "a1"の代わりに "a1"と "a2"につながります。 – gdrules