[英]Haskell kind system vs type families and multi param type classes
在 Haskell 中,我發現很難完全掌握類系統的目的,以及它真正為語言添加了什么。
我知道有種類會增加安全性。 例如,考慮fmap :: (a -> b) -> fa -> fb
與它的單一版本fmap2 :: (a -> b) -> p -> q
。
我的理解是,多虧了這種系統,我可以事先更詳細地指定數據的形狀應該是什么。 更好,因為類型檢查器可以檢查更多,更嚴格的要求將降低用戶混淆類型的可能性。 這將減少編程錯誤的可能性。 我相信這是種類的主要動機,但我可能是錯的。
現在我認為 fmap2 可以具有與 fmap 相同的實現,因為它的類型是不受約束的。 這是真的嗎?
是否可以將 base/ghc 庫中的所有多種類類型替換為單種類類型,並且它仍然可以正確編譯?
為了澄清一點,我的意思是對於像這樣的類:
class Functor f where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
我可能會用類似的東西代替它
class Functor a b p q where
fmap :: (a -> b) -> p -> q
(<$) :: a -> q -> p
像這樣的Functor
實例
instance Functor [] where fmap = map
我可能會替換它
instance Functor a b p q where fmap = map
備注:這不會按原樣工作,因為我還需要修改map
並沿着依賴鏈向下走。 以后會考慮更多。。
我想弄清楚種類是否不僅僅增加了安全性? 我可以用多種類型做一些我不能用單種類做的事情嗎?
備注:這里我忘了提到我通常使用一些語言擴展,通常是為了在編寫類時提供更大的靈活性。 在做 vanilla haskell 時,使用的東西真的很有意義。 但是當我開始使用類型系列和一些其他擴展時,我根本不需要種類就變得不太清楚了。
我記得有一些可單次遍歷的庫,它使用單一類型重新實現了許多標准庫函數,並使用類型族來泛化簽名。 這就是為什么我的直覺是,如果使用類型家族,多種類變量可能不會真正增加那么多的表達能力。 然而,這樣做的一個缺點是你失去了類型安全。 我的問題是你真的只是失去了那個,還是你真的失去了其他東西。
讓我們備份。 你似乎認為因為簽名
id2 :: a -> b
比
id :: a -> a
id2
可以與id
具有相同的實現。 但事實並非如此。 事實上id2
沒有完整的實現(任何id2
實現都涉及無限循環或undefined
)。
普遍性的結構會產生“壓力”,而這種壓力是我們必須導航才能為某事找到正確類型的原因。 如果f
是不是更寬泛g
,這意味着任何地方g
可以使用, f
也,但它也意味着,任何實現f
是一個有效的實現g
。 因此,在使用站點上,它朝一個方向發展,而在定義站點上,它朝另一個方向發展。
我們可以使用id2
任何地方,我們也可以使用id
,但簽名id2
是如此普遍,這是不可能實現的。 簽名越通用,可以使用的上下文就越多,但實現的可能性也就越小。 我想說一個好的類型簽名的主要目標是找到盡可能少的預期函數實現的通用級別,而不是完全不可能編寫。
您提議的簽名fmap2 :: (a -> b) -> p -> q
與id2
一樣,非常通用,無法實現。 -kinded更高類型的目的是給我們的工具,有一個像很一般簽名fmap
,這是不是太籠統像fmap2
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.