![](/img/trans.png)
[英]What is the difference between forall a. [a] and [forall a. a]?
[英]Why is `[1, "a"] :: [forall a. Show a => a]` not allowed?
在我(可能不正確)的理解中,以下兩個列表應該是等效的:
[1, "a"] :: [forall a. Show a => a]
data V = forall a. Show a => V a
[V 1, V "a"] :: [V]
但是,第一個不被接受,但第二個工作正常(使用ExistentialQuantification
)。
如果第一個列表不存在, map V :: ??? -> [V]
的空白中的類型是什么map V :: ??? -> [V]
map V :: ??? -> [V]
? 什么類型的機制強制包裝器的存在?
你的理解是不對的。 問題的很大一部分是您使用的傳統存在量化語法對於不完全熟悉它的人來說非常混亂。 因此,我強烈建議您改用 GADT 語法,這也有嚴格意義上更強大的好處。 最簡單的事情就是啟用{-# LANGUAGE GADTs #-}
。 在此期間,讓我們打開{-# LANGUAGE ScopedTypeVariables #-}
,因為我討厭想知道forall
在任何給定位置的含義。 您的V
定義與
data V where
V :: forall a . Show a => a -> V
如果我們願意,我們實際上可以刪除顯式forall
:
data V where
V :: Show a => a -> V
所以V
數據構造函數是一個函數,它接受任何可顯示類型的東西並產生V
類型的東西。 map
的類型非常嚴格:
map :: (a -> b) -> [a] -> [b]
傳遞給map
的列表中的所有元素都必須具有相同的類型。 所以map V
的類型就是
map V :: Show a => [a] -> [V]
現在讓我們回到你的第一個表達式:
[1, "a"] :: [forall a. Show a => a]
現在這實際上是說[1, "a"]
是一個列表,其每個元素的類型為forall a . Show a => a
forall a . Show a => a
。 也就是說,如果我提供任何a
Show
實例,則列表中的每個元素都應該具有該類型。 這是不正確的。 例如, "a"
沒有類型Bool
。 這里還有一個問題; 類型[forall a . Show a => a]
[forall a . Show a => a]
是“不可預測的”。 我不明白這意味着什么的細節,但松散地說,你在->
以外的類型構造函數的參數中堅持了forall
,這是不允許的。 GHC 可能會建議您啟用ImpredicativeTypes
擴展,但這確實不起作用,因此您不應該這樣做。 如果你想要一個存在量化事物的列表,你需要首先將它們包裝在存在數據類型中,或者使用專門的存在列表類型。 如果你想要一個普遍量化的東西的列表,你需要先把它們包裝起來(可能是新的)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.