2013-04-04 11 views
25

GHCのlexically scoped type variablesを使用する場合は、explicit universal quantificationも使用する必要があります。それはあなたが、関数の型シグネチャにforall宣言を追加する必要があり、次のとおりです。スコープタイプの変数には明示的なforallsが必要です。どうして?

{-# LANGUAGE ExplicitForAll, ScopedTypeVariables #-} 

f :: forall a . [a] -> [a]  -- The `forall` is required here ... 
f (x:xs) = xs ++ [x :: a]  -- ... to relate this `a` to the ones above. 

これは実際に定量化を行うには何も持ってない、または拡張ライターはちょうどのための便利なマーカーとしてforallキーワードをcooptんでした新しい、より広いスコープが適用されますか?

つまり、いつものようにforallを除外することはできませんか?関数本体内のアノテーションの型変数は、関数シグネチャ内の同じ名前の変数を参照していることは明確ではないでしょうか?または、タイピングが何らかの形で問題になるかあいまいになるか?

+1

私は自分の答えを以下に提出しましたが、私が考慮していない微妙な要素があるかどうかは疑問です。 ... – pash

+9

Haskell-98はスコープを持っていないので、forallによって導入されたスコープ付き変数のみを持つことは妥協です。そうすることで、ScopedTypeVariablesを有効にするときに古いコードが動作するようになります。 (間違いなく、Haskellは常にスコープ付きの型変数を持っていなければなりません) – augustss

答えて

24

はい、量指定子は意味があり、型が意味を成すために必要です。

まず、ハスケルには "非定量化"型署名というものはありません。 forallのない署名は、実際に暗黙のうちに定量化されます。このコードは...

f :: [a] -> [a]       -- No `forall` here ... 
f (x:xs) = xs ++ [x :: a]    -- ... or here. 

は...本当にこのことを意味します

f :: forall a . [a] -> [a]    -- With a `forall` here ... 
f (x:xs) = xs ++ [x :: forall a . a] -- ... and another one here. 

それでは、これが言うことを理解しましょう。重要なことは、fxのシグネチャのaという型変数が、の別の個の限定子にバインドされていることに気づくことです。これは、名前を共有しているにもかかわらず、異なるの変数であることを意味します。したがって、上記のコードでは、これに相当します、それは今や明らかだ区別名前で

f :: forall a . [a] -> [a] 
f (x:xs) = xs ++ [x :: forall b . b] -- I've changed `a` to `b` 

だけでなくfxのための署名で型変数は無関係ですが、ということx請求のための署名xができることanyタイプがあります。しかし、これは不可能です。xは、fが引数に適用されたときに、特定の型がaにバインドされている必要があるためです。実際には、型チェッカーはこのコードを拒否します。 f ...

f :: forall a . [a] -> [a]    -- A `forall` here ... 
f (x:xs) = xs ++ [x :: a]    -- ... but not here. 

のシグネチャで単一forallで... xの署名でaf年代の初めに数量詞に拘束される一方

、したがって、aはの署名にaという変数で表される型と同じ型を表します。

+0

https://downloads.haskell.org/~ghc/7.8.2/docs/html/users_guide/other-type-extensions.html#scoped-型変数では、式やパターン型のシグネチャでもこの種のスコープを行うことができます。パターン・タイプの署名はあまり理解できません。 – CMCDragonkai

+0

ScopedTypeVariablesを有効にしてもExplicitForAllを有効にしないとどうなりますか?そうすれば 'forall'と書くことはできません。 ScopedTypeVariablesの効果は何ですか?私が書いたスニペットでは、ScopedTypeVariablesは、特定の値が関数本体の中に 'Char'型であることを宣言することを可能にしました。 ScopedTypeVariablesがなければ、私はそれを書くことができませんでした。どの型変数を統一しようとしているわけではないので、奇妙です。 – CMCDragonkai

+0

@CMCDragonkai、 '-XScopedTypeVariables'は基本的に' -XExplicitForAll'なしでは役に立たない。時間の半分、私は後者を設定して、それが問題だと気づく前に5分間私の髪を引き裂くことを忘れてしまいます。 – pash

関連する問題