1

If Then Else の定義のプロジェクションに問題があります。実際には If-Else-Then として実行されています。

 import Prelude hiding (pred,and,or,not)

 data PR = Z
     | S
     | P Int
     | C PR [PR]
     | PR PR PR
     deriving Show
 eval :: PR -> [Integer] - Integer
 eval Z _ = 0
 eval S [x] = x+1
 eval (P n) xs = nth n xs
 eval (C f gs) xs = eval f (map (\g -> eval g xs) gs)
 eval (PR g h) (0:xs) = eval g xs
 eval (PR g h) (x:xs) = eval h ((x-1) : eval (PR g h) ((x-1):xs) : xs)

 nth _ [] = error "nth nil"
 nth 0 _ = error "nth index"
 nth 1 (x:_) = x
 nth (n) (_:xs) = nth (n-1) xs

 one = C S [Z]
 plus = PR (P 1) (C S [P 2])
 ife = PR (P 1) (C (P 2) [P 3, P 4])

スワップしようとするP 3と、P 4完全に壊れます(毎回「then」値を返します)。ite[0,2,3]戻る必要があり、戻る必要が3あります。代わりに、反対のことが起こっています。どうすればこれを修正できますか?ite[1,2,3]2

4

2 に答える 2

5

このクラスはどうですか?私はあなたと私が非常によく似た宿題をしているのに気づきました。非常によく似ています。

まず、IF-Then-Else モデルをエミュレートするプリミティブ再帰関数を作成します。したがって、

eval ite [0,1,2] => 1

eval ite [1,2,3] => 3

あなたが提供したもので、最初の入力に応じて反対のインスタンスで同じ品質の関数を取得しているようです。

ife = PR (P 1) (C (P 2) [P 3, P 4])

今あなたの機能は何を言っていますか?ITE の実装では、条件に基づいて実行を 2 つの異なる式に分割できるため、プリミティブな再帰構造が使用されます。ブール代数で使用されるのと同じ条件。0 の場合は false です。それ以外の場合、数値が何か (0<) に評価される場合は true です。PR コンストラクトは、「スタック」の先頭が 0 の場合は最初の引数を評価することでこれを行います。それ以外の場合は、行のどこかで終了することを期待して 2 番目の引数を評価します (多くの場合、カウンターとして先頭をデクリメントし、最終的には最初の引数を実行します)。しかし、すべての意図と目的のために、2 番目の式は (0<) で実行されると言えます。

ふぅ!では、実装をどのように修正しますか!? 簡単:

ife = PR (P 2) (C (P 1) [P 3, P 4])

2 つの投影を逆にしただけなので、それらを切り替えます。スタックの先頭が Z の場合は 2 番目の式を射影し、それ以外の場合は最初の式を射影します。またはさらに良い:

ite = PR (P 2) (P 1)

宿題もまだ終わっていないと思います。間違っている場合は、追加の洞察をいただければ幸いです。

于 2012-11-26T08:05:54.343 に答える