Haskell'de türler silindi mi?


13

Haskell, ortak lisp ile belirgin bir benzerliğe sahip olan “jenerik fonksiyonlar” kavramına sahiptir - Haskell ile ne deneyimi ne de ortak lisp ile deneyime sahip değilim, burada çok yakın olabilirim. Bu to_string, tüm türler için dize temsili tanımlamak üzere genel bir tesis tanımlayabileceğiniz anlamına gelir . Tabii ki, tesis özel durumlarda tanımlanmalıdır, ancak to_stringimzası olan bir işlev vardır α → string.

Hasamell'de OCaml'de olduğu gibi türler siliniyor mu? Cevabınız evet ise, Haskell'de “genel fonksiyonlar” ın uygulanması, türlerin dinamik olduğu ve dolayısıyla silinmediği yaygın lisp uygulamasından nasıl farklıdır?

Uygulama ayrıntılarının derleyiciye özgü olduğunu anlıyorum, ancak muhtemelen birçok uygulamada veya tüm uygulamalarda ortak hükümler vardır.


5
Önemsiz türde bir işlev tanımlayamayacağınızı unutmayın a -> String. Daha büyük olasılıkla, bir tür kısıtlamanız olur Show a => a -> String.
DJG

Yanıtlar:


16

Cevap şimdiye kadar yanıltıcı.

"Parametrik" ve "ad-hoc aşırı yükleme" polimorfizmi arasında bir ayrım yapılması gerekmektedir. Parametrik, "tüm a türleri için aynı şekilde davranır" anlamına gelirken, "ad-hoc" - Simon'un polimorfik olarak adlandırdığı şey - uygulamayı türe göre değiştirir.

Her ikisine örnek olarak reverse :: [a] -> [a]parametrik olan ve show :: Show a => a -> String"ad-hoc" aşırı yüklenmiş olan örnek gösterilebilir.

Daha soyut bir sezgi istiyorsanız, "sahip olmak" veya "düşünmek" gibi nesneler için herhangi bir kısıtlama getirmeyen, ancak " açmak "dediğimiz şeylerin açılmasını gerektirir. Örneğin 'bir ağaç açmak' mantıklı değilken, 'bir kapı düşünebilirim' ve 'bir kapı açabilirim'. Örneği daha ileri götürmek, "açmak", "pencereyi açmak" ve "müşteri hizmetleriyle bir şikayet bileti açmak" gibi "geçici polimorfik" olmaktan çok farklı şeylerdir. Bu zorlanmış görünüyorsa - unutun! Benim için çalışıyor.

Ancak her ikisi de derleme zamanında çözümlenir ve aslında "silinir". Modülo çeşitli GHC uzantıları ve Şablon Haskell, vb Çeşitleri vardır aslında derleme zamanında silinip çalışma zamanında kontrol asla.

Parametrik olarak polimorfik fonksiyonlar tüm tipler için aynı şekilde davranır, bu nedenle derleyici belirli bir program noktasında hangi "tip-sınıflı" fonksiyon versiyonunun çalıştırılması gerektiğine karar verirken, sadece bir kod parçasının oluşturulması gerekir. Bu nedenle, tür sınıfı başına tür başına bir eşgörünümün ve karşılık gelen "newtype" çözümünün var olmasının nedeni de budur.

Uygulama, SPJ'ler ders kitabında ve Wadler ve Blotts yazı tiplerinde ayrıntılı olarak açıklanmıştır .


Cevabımı silmem gerektiğini mi düşünüyorsun?
Simon Bergot

Hayır, tam kelime dağarcığına çarpmamanız konusunda uyarınız iyi
:)

GHC'nin türleri silmesinin neden mümkün olduğunu biraz genişletebilir misiniz? Temel yazım sayesinde mi?
Simon Bergot

2
Genel olarak çalışma zamanında ya parametrik olarak polimorfik fonksiyonlar sadece bir kez var olabilir ve geçici bir polimorfik fonksiyonlar bazı sanal gönderme yöntemi ile çağrılabilir ya da her bir kod için tüm kodlar ayrı ayrı oluşturulabilir ve statik olarak bağlı çağrılar yapılabilir. Her iki uygulama da dil açısından doğrudur (Haskell'in polimorfik türleri olmadığını unutmayın; böyle bir şey sadece GHC foralluzantısı ile oluşturulabilir ).
Jan Hudec

Türlerin silinmesine izin vermeyen herhangi bir GHC uzantısı var mı? Aşırı yükleme statik ve tam bağımlı tipler olmadan hiçbir şey düşünemiyorum
Daniel Gratzer

1

Uyarı: CS'deki geçmişim çok güçlü değil, bu yüzden her zaman doğru kelimeleri kullanamayabilirim ve bazı noktalarda yanlış olabilirim. Her neyse, işte benim anlayışım:

Bence jenerik ilaçları polimorfizmle karıştırıyorsunuz.

Gibi genel tip List<Foo>parametre olarak diğer türleri almak türleri tarif eder ve daha zengin tip kontrolü sağlamak için kullanılır.

Haskell'de genel bir işlev olabilir count:: List a -> Int. Her tür listeyi kabul eder ve eleman sayısını döndürür. Sadece bir uygulama var.

Genellikle, List'i tanımlarken, T hakkında hiçbir şey üstlenemezsiniz. Sadece saklayabilir ve geri verebilirsiniz.

Sizin to_stringişlevi farklı koşullar altında farklı davranır aracı bir polimorfik bir fonksiyondur. Haskell'de bu, türler için sıfatlar gibi çalışan tipik sınıflarla yapılır.

ShowBir show :: a -> Stringişlevi tanımlayan bir tip sınıfınız var .

Bir tür , tip sınıfını Foouyguladığında Show, tanımını sağlamalıdır show. Bu tip daha sonra Showniteleyici gerektiren işlevlerde kullanılabilir (olduğu gibi Show a => a -> whatever). Haskell türleri silemez, çünkü bu işlevler işlevin doğru uygulamasını bulmak zorundadır show.


Yaygın lispte, polimorfik fonksiyonlara “jenerik fonksiyonlar” IIRC denir ve ben aynı (kafa karıştırıcı) kelimeleri kullandım. Cevabınız faydalı ve son argümanınız oldukça inandırıcı. .-)
user40989

“Sadece tek bir uygulama var” - sadece mantıklı olan, tabii ki, ama sonsuz sayıda mümkün. A → b türünde bir işlev vardır | b | ^ | a | olası uygulamalar (Bool → Bool türündeki işlevlerin sayısını göz önünde bulundurun) ve listelerin üst boyut sınırı yoktur.
Jon Purdy
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.