あなたの理解は正しくありません。この問題の大きな部分は、使用してきた伝統的な存在量の構文が、それに精通していない人にとってはかなり混乱しているということです。したがって、代わりにGADT構文を使用することを強くお勧めします.GADT構文は厳密に強力です。簡単なことは、{-# LANGUAGE GADTs #-}
を有効にすることです。私たちがいる間に、が何を意味するのか不思議に思っていないので、{-# LANGUAGE ScopedTypeVariables #-}
をオンにしましょう。
data V where
V :: Show a => a -> V
のでV
データコンストラクタは任意の showableの何かを取る関数である:あなたのV
定義は、私たちが好きなら私たちが実際に明示的なforall
をドロップすることができ
data V where
V :: forall a . Show a => a -> V
とまったく同じことを意味し、タイプV
のものが生成されます。 map
の種類はかなり制限されていますmap
に渡されたリストのすべての要素は同じ型を持っている必要が
map :: (a -> b) -> [a] -> [b]
。だから、map V
の種類は、ちょうど
map V :: Show a => [a] -> [V]
さんはすぐに戻ってあなたの最初の式を取得してみましょうされています
[1, "a"] :: [forall a. Show a => a]
を今、これは実際に言う[1, "a"]
は、その要素のそれぞれがforall a . Show a => a
型を持つ、リストであるということです。つまり、Show
のインスタンスであるa
を指定すると、リストの各要素はその型を持つ必要があります。これは単に真実ではありません。 "a"
は、たとえば、タイプがBool
ではありません。ここにはもう一つの問題があります。タイプ[forall a . Show a => a]
は「批判的」です。私はその意味を理解していませんが、->
以外の型コンストラクタの引数にはforall
がついています。これは許されません。 GHCはImpredicativeTypes
拡張機能を有効にすることを提案しているかもしれませんが、実際にはうまくいきません。存在を定量化したもののリストが必要な場合は、まずそれらを実在するデータ型で囲むか、特殊な実在リスト型を使用する必要があります。普遍的に数量化されたもののリストが必要な場合は、まずそれらを(おそらくnewtypesで)ラップする必要があります。
これは常に私を悩ませています。私はそれが嫌いです。[show 1、show "a"] 'と' map show [1、 "a"]は同じではありません。 –