Anlayışınız doğru değil. Sorunun büyük bir kısmı, kullandığınız geleneksel varoluşsal nicelendirme sözdiziminin, tam olarak aşina olmayanlar için oldukça kafa karıştırıcı olmasıdır. Bu nedenle, kesinlikle daha güçlü olmanın yararına sahip olan GADT sözdizimini kullanmanızı kesinlikle tavsiye ediyorum. Yapılması kolay olan şey sadece {-# LANGUAGE GADTs #-}
'u etkinleştirmektir. Biz bu işteyken, {-# LANGUAGE ScopedTypeVariables #-}
'u açalım, çünkü herhangi bir noktada forall
'un ne anlama geldiğini merak etmekten nefret ediyorum.
data V where
V :: Show a => a -> V
Yani V
veri yapıcısı herhangi showable şey götüren bir fonksiyonudur: Sizin V
tanım Eğer isterseniz biz aslında açık forall
bırakabilirsiniz
data V where
V :: forall a . Show a => a -> V
tam olarak aynı şeyi ifade yazın ve V
türünde bir şey üretir. map
tipi oldukça kısıtlayıcı: map
geçirilen listenin
map :: (a -> b) -> [a] -> [b]
Tüm elemanlar aynı türde olması gerekir.
[1, "a"] :: [forall a. Show a => a]
Şimdi ne olacak bu aslında diyor
[1, "a"]
bir liste olan unsurlar vardır
forall a . Show a => a
yazın her biri olmasıdır: Yani
map V
tipi en Artık ilk ifadesi dönelim sadece
map V :: Show a => [a] -> [V]
olduğunu. Yani, 'un bir örneği olan a
'u sağladım, listenin her bir öğesi bu türde olmalıdır. Bu doğru değil. "a"
, örneğin, Bool
türüne sahip değildir. Burada başka bir sorun var; [forall a . Show a => a]
türü "engellenmez" dir. Bunun ne anlama geldiğini anlayamıyorum, ama gevşek bir şekilde forall
'u ->
'dan başka bir tür yapıcı argümanında sıkıştırabildiniz ve buna izin verilmiyor. GHC, ImpredicativeTypes
uzantısını etkinleştirmenizi önerebilir, ancak bu gerçekten doğru çalışmıyor, bu yüzden yapmamalısınız. Varoluşsal olarak nicelendirilmiş şeylerin bir listesini istiyorsanız, önce varoluşsal veri türlerinde bunları tamamlamanız veya özel bir varoluşsal liste türü kullanmanız gerekir. Eğer evrensel olarak ölçülen şeylerin bir listesini istiyorsanız, önce onları (muhtemelen yeni tiplerde) sarmanız gerekir.
Bu her zaman beni tahrik etti. Bundan nefret ediyorum ki, "show 1, show" a "] ve" show "[1," a "]' aynı değil. –