2012-04-12 4 views
8

私はforallとそれほど慣れていないけど、最近この質問読み:答えの一つでWhat does the `forall` keyword in Haskell/GHC do?なぜforall(RankNTypesの使用法)がデフォルトで適用されないのですか?

がこの例である:

{-# LANGUAGE RankNTypes #-} 
liftTup :: (forall x. x -> f x) -> (a, b) -> (f a, f b) 
liftTup liftFunc (t, v) = (liftFunc t, liftFunc v) 

説明は良好であり、私はforallがここでやっていることを理解しています。しかし、これがデフォルトの動作ではないという特別な理由があるのだろうかと疑問に思っています。それは不利な時間がありますか?

編集:つまり、デフォルトでforallを挿入できない理由はありますか?

+3

なぜ拡張子がデフォルトでオンでないのか、なぜ '(x - > fx) - >(a、b) - >(fa、fb) 'は(forall x。x - > fx) - >(a、b) - >(fa、fb)'と同じように扱われません。後者の場合は、コンパイラが 'forall'をどこに挿入するかを決定するロジックを指定できますか? – sepp2k

+0

後者ですが、私はこの件に関して全く何も提案し始めるべきではありません! –

+0

'(x - > f x) - >(a、b) - >(f a、f b)'という型はかなり役に立たないことに注意してください。関数はタプルのいずれかの要素に第1引数を適用できないため、結果は '⊥'または'(⊥、⊥) 'でなければなりません。 – hammar

答えて

16

これはHaskell 2010標準の一部ではないため、デフォルトではオンではなく、代わりに言語拡張として提供されています。なぜそれが標準にないのかについては、rank-n型は、標準のHaskellが持つ普通のrank-1型よりも実装するのがかなり困難です。それらは頻繁に必要とされるものではないので、委員会は言語と実装の単純さの理由からそれらを気にしないことにしました。

もちろん、ランクn型は有用ではありません。彼らは非常にそうであり、それらなしではST monadのような貴重なツールはありません(IOのような効率的でローカルな可変状態を提供します)。IORefを使用してください。しかし、これらは言語にかなりの複雑さを加えます。そして、見た目の良さのようなコード変換を適用すると、不思議な動作を引き起こす可能性があります。たとえば、ランクn型チェッカーの中には、runST (do { ... })が許可されますが、2つの式が常にランクn型なしで同等であっても、runST $ do { ... }は拒否されます。予期しない(場合によっては厄介な)動作の例については、this SO questionを参照してください。

sepp2kを尋ねるように、あなたが代わりに求めている、場合forallが明示的に増加した汎用性を得るために署名を入力して追加する必要がある理由は、問題が(forall x. x -> f x) -> (a, b) -> (f a, f b)が実際に(x -> f x) -> (a, b) -> (f a, f b)よりも限定型であることです。後者では、x -> f x(任意のfx)の形式の関数を渡すことができますが、前者では、渡す関数はすべてxの関数でなければなりません。したがって、たとえば、タイプString -> IO Stringの関数は、2番目の関数には許容される引数ですが、最初の関数は許容されません。代わりにタイプa -> IO aが必要です。後者が自動的に前者に変換されたのはかなり混乱します!彼らは2つの非常に異なるタイプです。それは暗黙のforall秒でより多くの意味をなすかもしれない

は、明示的に:

forall f x a b. (x -> f x)   -> (a, b) -> (f a, f b) 
forall f a b. (forall x. x -> f x) -> (a, b) -> (f a, f b) 
+0

私はこれをもう少し消化する必要があると思います:) –

+0

また、2次以上の多型については、最も一般的な型である '∀b 'はありません。 (∀a。a→b)→(b、b) 'は∀c dより一般的ではない。 (∀a b。a→b)→(c、d) 'とは逆でもない。そして、型推論は一次多型と二次多型に対して決定可能であるが、3次以上の型推論ではない。 – Vitus

+0

@vitus - 二次多型の決定可能性についてのリファレンスを提供できますか?私はそれに慣れていない。 –

7

私はthey make type inference undecidableため、上位タイプがデフォルトで有効になっていないと思われます。これは拡張機能を有効にしてもforallキーワードを使用して上位ランクのタイプを取得する必要がある理由です。GHCでは、できるだけ多くのタイプ情報を推測するために明示的に指示されない限り、すべてのタイプはランク1です。

他の言い方をすれば、より上位のタイプ(forall x. x -> f x) -> (a,b) -> (f a, f b)を推論する一般的な方法はないため、そのタイプを取得する唯一の方法は、明示的なタイプシグニチャによる方法です。

編集:上記のVitusのコメントごとに、ランク2型の推論は決定可能ですが、上位の多型はありません。したがって、この型シグネチャは技術的に推測不可能です(アルゴリズムはより複雑です)。ランク2の多態型推論を有効にする余分な複雑さが議論の余地があるかどうかは議論の余地がありますか...

関連する問題