コードAllowAmbiguousTypesとは何ですか?なぜこの "forall"の例ではなぜ必要ですか?
{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
-- I know this particular example is silly.
-- But that's not the point here.
g :: forall a . RealFloat a => Bool
g = True
main :: IO()
main = print (g @Double)
だからAllowAmbiguousTypes
を追加すると、コードのコンパイルを行いますエラー
• Could not deduce (RealFloat a0)
from the context: RealFloat a
bound by the type signature for:
g :: RealFloat a => Bool
at app/Main.hs:3:6-35
The type variable ‘a0’ is ambiguous
• In the ambiguity check for ‘g’
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature:
g :: forall a. RealFloat a => Bool
でGHC 8.0でコンパイルに失敗します。ここで
私の質問は以下のとおりです。
- 正確
AllowAmbiguousTypes
は何? - この特定のコードを動作させる必要があるのはなぜですか?
- 私は
AllowAmbiguousTypes
を追加すると、私が本当にこの特定のコードに必要以上のことを与えていることを恐れています。それは恐ろしいように聞こえる。これは、Haskellの型システムの安全性を損なう可能性があります。おそらく、この特定のコードとは関係のない他の領域ではおそらく安全です。これらの恐怖は根拠がありませんか? - 代替手段はありますか?この場合、Haskellは私が決して聞いたことのない型変数
a0
を挿入しているようです。これらの無関係な型変数を作成しないようにHaskellに指示する拡張子はありません - 明示的に私自身が明示的に指定したものだけを使用して、自分の明示的なforall a
で追加しますか? - user2407038さんのコメントのために1つの質問が追加されました:あなたはその
AllowAmbiguousTypes
は名前の誤りですか?AllowUnusedTypeVariables
という名前の方がいいでしょうか?
あいまいな型は、その型の変数(型の '=>')の本文には言及されていない型変数を持つ型です。 'RealFloat a => ..'は' ..'が 'a'を言及していないときはあいまいです。あいまいな型は一般的にプログラマーのエラーであり、TypeApplicationsの前ではまったく役に立たなかったので、それらを許可する拡張が必要です。最後の2つの質問のために、それはどのようにしても型チェックを「安全でない」ものにしません。 'RealFloat a => Proxy a - > Bool'と書くこともできます。ここで[Proxy](https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Proxy.html)は次のようになります。ここに。 – user2407038
代わりに 'RealFloat a => Tagged a Bool'を使うことができます。ここで、' Tagged'は 'tagged'パッケージから来ており、場合によってはプロキシの方法よりも効率的です。 – dfeuer
'AllowAmbiguousTypes'は私の目では無害です。多くのラムダ計算では、型は常に明示的に渡されます(例えば 'map @ a @b f xs')。普通のハスケルでは、タイプが推論されています。つまり、それらを渡す必要はありません(良い)ことを意味し、必要であってもそれらを渡すことはできません。そのため、引数の型や戻り値から推測できないタイヴァー型の型は禁止する必要があります。それゆえ、私たちはそれらを推測不能にするためだけにプロキシ/タグ付けを使用しなければなりません。しかし、現在、GHCは明示的な型のアプリケーションを許可しているので、もはやそれを行う必要はありません。 – chi