Golang / Haskell'de tür çıkarımı


9

Go'nun aslında ML veya Haskell gibi fonksiyonel dillerin sahip olduğu anlamında gerçek bir tür çıkarımın olmadığını okudum, ancak iki versiyonun karşılaştırmasını anlamak için basit bir şey bulamadım. Birisi Go'daki tür çıkarımının Haskell'deki tür çıkarımından ve her birinin artı / eksilerinden nasıl farklı olduğunu açıklayabilir mi?

Yanıtlar:


13

Go'nun tür çıkarımıyla ilgili bu StackOverflow yanıtına bakın . Kendime Go aşina değilim ama bu cevaba dayanarak (bazı C ++ teminoloji ödünç almak için) tek yönlü bir "tür kesinti" gibi görünüyor. Bu, eğer varsa:

x := y + z

daha sonra derleyici için yapılması önemsiz bir şey olan xtürün y + zanlaşılmasıyla türetilir. Bunu yapmak için, a priori türleri yve zbilinmesi gerekir : bu, tür ek açıklamaları ile yapılabilir veya kendilerine atanan hazır bilgilerden çıkarılabilir.


Aksine, çoğu işlevsel dilde, değişkenlerin türünü türetmek için bir modül (veya çıkarım algoritması yerel ise işlev) içindeki tüm olası bilgileri kullanan tür çıkarımları vardır. Karmaşık çıkarım algoritmaları (Hindley-Milner gibi) genellikle sahnelerin arkasında bir tür tip birleşimi (biraz denklem çözme gibi) içerir. Örneğin, Haskell'de şöyle yazarsanız:

let x = y + z

Haskell, türü sadece xdeğil, aynı zamanda yve zsadece onlara ekleme yaptığınız gerçeğine dayanarak çıkarabilir . Bu durumda:

x :: Num a => a
y :: Num a => a
z :: Num a => a

(Buradaki küçük harf , C ++ gibi diğer dillerde genellikle "jenerik" olarak adlandırılan abir polimorfik türü belirtir . Num a =>Bölüm, tür desteğinin bir miktar ekleme kavramına sahip olduğunu gösteren bir kısıtlamadıra .)

İşte daha ilginç bir örnek: herhangi bir özyinelemeli fonksiyonun tanımlanmasına izin veren sabit nokta birleştirici:

let fix f = f (fix f)

Haskell derleyicisinin türünü hiçbir yerde fbelirtmediğimize veya türünü belirtmediğimize fixdikkat edin:

f :: t -> t
fix :: (t -> t) -> t

Bu diyor ki:

  • Parametre f, rastgele türden taynı türe kadar bir işlev olmalıdır t.
  • fix, bir tür parametresi alan t -> tve bir tür sonucu döndüren bir işlevdir t.

4
daha doğrusu Haskell söyleyebilirim x, y, zaynı Num, Eric tipi ama hala olabilir Integerler, Doublelar, Ratio Integers ... Haskell diğer typeclasses için sayısal türleri arasında keyfi bir seçim yapmak için istekli ama değil.
John Dvorak

7

Go'daki tür çıkarımları son derece sınırlıdır ve son derece basittir. Yalnızca bir dil yapısında (değişken bildirimi) çalışır ve sadece sağ tarafın türünü alır ve sol taraftaki değişkenin türü olarak kullanır.

Haskell'deki tür çıkarımı her yerde kullanılabilir, tüm program için türleri çıkarmada kullanılabilir. Birleşmeye dayanır, yani (kavramsal olarak) tüm türler "bir kerede" çıkarılır ve hepsi birbirlerini etkileyebilir: Go'da, tür bilgisi yalnızca değişken bir bildirimin sağ tarafından soldan el tarafı, asla diğer yönde ve asla değişken bir bildirimin dışında değil; Haskell'de, tür bilgisi tüm program boyunca her yöne serbestçe akar.

Ancak, Haskell'ın tür sistemi tür kesmesi aslında böylece güçlüdür başarısız (: kısıtlamalar türü her zaman çıkarılabilir, böylece yerine koymak lazım daha doğrusu) bir türünü tahmin etmek. Go'nun tip sistemi o kadar basittir (alt tipleme yok, parametrik polimorfizm yok) ve çıkarımı o kadar sınırlıdır ki, her zaman başarılı olur.


4
"Haskell'de, bilgi tüm program boyunca her yöne serbestçe akar": Bunun çok iyi bir sezgi verdiğini düşünüyorum. +1
Giorgio

Bu cevabın son paragrafta iddia ettiği iddialar biraz yanıltıcıdır. Haskell'in alt türü yoktur. Ayrıca, parametrik polimorfizm tip çıkarımının bütünlüğü için herhangi bir soruna neden olmaz: Polimorfik lambda hesabı üzerinde Hindley-Milner her zaman en genel türü bulur. Haskell türleri çıkartamayabilir, ancak bu, naif olarak formüle edildiğinde hiçbir ana (yani, "en iyi seçim") türünün olmadığı GADT'ler gibi karmaşık tip sistem özellikleri üzerinde olacaktır.
Edward Z. Yang
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.