13

, eşdeğer olmalıdır:Neden [1, "a"] :: [forall a. Göster a => a] `ye izin verilmiyor mu? iki liste aşağıdaki benim (kudreti yanlış) anlayışında

[1, "a"] :: [forall a. Show a => a] 

data V = forall a. Show a => V a 
[V 1, V "a"] :: [V] 

Ancak ilki kabul edilmez fakat ikinci bir (ExistentialQuantification ile) çalışıyor.

İlk liste yoksa, map V :: ??? -> [V] boş sayfasındaki yazı ne olurdu? Ne tür mekanizma sarıcının varlığını zorlar?

+0

Bu her zaman beni tahrik etti. Bundan nefret ediyorum ki, "show 1, show" a "] ve" show "[1," a "]' aynı değil. –

cevap

13

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.