2012-10-02 12 views
51

ハスケルはseqという名前の魔法の関数を持っています。これは任意の型の引数をとり、それを弱Head Normal Form(WHNF)に減らします。なぜseqが悪いですか?

私は「多型seqが悪い」と主張している[...私は、彼らが今た人覚えていないこと]ソースのカップルを読みました。どのようにして彼らは「悪い」ですか?

同様に、rnf関数があり、引数を標準形式(NF)に減らします。しかし、このはクラスメソッドです。任意の型に対しては機能しません。 seqに似た組み込みのプリミティブとしてこれを提供するために、言語仕様を変更することができることは私には明らかです。これはおそらく、単に「seq」を持つよりも「さらに悪い」ことになります。これはどういう意味ですか?

最後に、誰かがseqrnfparを与えるとすると、それは今であるように、むしろconst機能より、id関数と同じタイプをsimilars改善であろうことを示唆しました。どうして?私の知る限り、それは自由な定理を弱めないか、言い換えれば、seqせずに有効ないくつかの等式は、もはやseqで有効です。ので、多型seq機能が悪いです知っているよう

+22

'seq'機能は、我々は' seq'を持っているとき、ラムダ計算からのすべての結果は、もはや、信頼できないことを意味ラムダ定義可能(I.R.、ラムダ計算に定義することはできません)、ではありません。 – augustss

答えて

49

例えば、平等

map g (f xs) = f (map g xs) 

は、すべての機能g :: tau -> tau'、すべてのリストxs :: [tau]及び全ての多機能f :: [a] -> [a]のために保持しています。基本的には、fは、引数リストの要素を並べ替えたり、要素を削除または複製したりすることはできますが、新しい要素を作成することはできません。

正直なところ、エラーの種類がポリモーフィックなので、非終端計算/ランタイムエラーをリストに「挿入」する可能性があるため、要素を作成できます。つまり、この平等はすでにseqのないHaskellのようなプログラミング言語で壊れています。以下の関数定義は、方程式の反例を提供します。基本的に、左側のgはエラーを「隠す」。式を固定するために

g _ = True 
f _ = [undefined] 

gは厳密でなければならない、すなわち、それはエラーにエラーをマッピングしなければなりません。この場合、再び平等が成立する。

多形seq演算子を追加すると、式が再び破損します。たとえば、次のインスタンス生成は反例です。

g True = True 
f (x:y:_) = [seq x y] 

我々はリストxs = [False, True]を考えると、私たちはある一方

f (map g [False, True]) = f [undefined, True] = [undefined] 

に、あなたが特定の要素を作るためにseqを使用することができ、

map g (f [False, True]) = map g [True] = [True] 

を持っていますが、リストの位置は、リスト内の別の要素の定義に依存します。 gが合計である場合、等式は再び成立する。あなたが自由な定理でinteresetedされている場合、あなたはエラーやseqでさえ、言語と言語を検討しているかどうかを指定することを可能にする、free theorem generatorをチェックしてください。これはあまり実用的な関連性があるように見えるかもしれません、が、seqfoldr/build融合がseqの存在下で失敗し、例えば、機能的なプログラムのperformenceを改善するために使用されるいくつかの変換を破ります。 seqの存在下で無料定理についてもっと詳しく知りたい場合は、Free Theorems in the Presence of seqを見てください。

ポリモーフーフseqは、特定の変換が言語に追加されたときに破損することが分かっていました。しかし、南方にも欠点がある。あなたがseqをベース型クラスを追加する場合は、あなたがどこかに深いダウンseqを追加する場合は、あなたのプログラムに型クラス制約の多くを追加する必要があります。さらに、seqを使用して修正できるスペースリークが既にあることが判明したので、seqを省略することは選択肢ではありませんでした。

最後に、私は何かが恋しいかもしれませんが、a -> aseq演算子がどのように機能するかわかりません。 seqの手がかりは、他の式が正規形になると評価された場合に、正規形にする式を評価することです。 seqのタイプがa -> aの場合、別の式の評価に依存して1つの式の評価を行う方法がありません。

+0

'map g(f xs)= f(map g xs)' Uhh ... 'undefined'や 'seq'を持たない言語であっても。 xs = [[3]、[4]] 'は、まったく空想的ではありませんが、絶対にその平等を破りません。私は本当に明白な何かを見逃しているのですか、基本的にこの完全な答えには深刻な欠陥がありますか? – semicolon

+0

@semicolon定理は多型の 'f'について取り上げています。新しい型の要素を作成することはできません。あなたの 'f'は少なくとも' Num'制約を必要としますが、 '[a] - > [a]'はできません。 – Ben

+0

@Benああ、私の悪い、それは理にかなっています。 – semicolon

8

this answer - 別の反例はsequndefinedでモナドの法則を満たしていません。 undefinedはチューリング完全言語では避けられないので、責任を負うのはseqです。

関連する問題