Neden daha yüksek çeşitlere ihtiyacınız var?


13

Bazı diller (örneğin tip parametreler ile sınıflar ve fonksiyonlar için izin List<T>nerede Tkeyfi bir tür olabilir). Örneğin, aşağıdaki gibi bir işleve sahip olabilirsiniz:

List<S> Function<S, T>(List<T> list)

Bununla birlikte, bazı diller bu kavramın bir seviye daha yüksek olmasına izin vererek imzayla bir işleve sahip olmanızı sağlar:

K<S> Function<K<_>, S, T>(K<T> arg)

Nerede K<_>kendisi gibi türüdür List<_>bir tür parametresi vardır. Bu "kısmi tip" bir tip yapıcısı olarak bilinir.

Sorum şu, neden bu yeteneğe ihtiyacınız var? Gibi bir tipe sahip olmak mantıklıdır List<T>çünkü hepsi List<T>neredeyse tamamen aynıdır, ancak hepsi K<_>tamamen farklı olabilir. Ortak bir işlevselliği olmayan bir Option<_>ve a'ya sahip olabilirsiniz List<_>.


7
Burada birkaç iyi yanıt var: stackoverflow.com/questions/21170493/…
itsbruce

3
@itsbruce Özellikle, FunctorLuis Casillas'ın cevabındaki örnek oldukça sezgisel. Ne yapar List<T>ve Option<T>ortak noktası vardır? Bana bir ve bir işlev T -> Sverirsen sana bir List<S>veya verebilirim Option<S>. Ortak bir nokta da Ther ikisinden de bir değer elde etmeye çalışabilmenizdir .
Doval

@Doval: İlkini nasıl yapardın? İkincisi ile ilgilendiği ölçüde, bunun her iki türün de uygulanmasıyla halledilebileceğini düşünüyorum IReadableHolder<T>.
supercat

ben tahmin olduğum @supercat onlar uygulamak zorunda kalacak IMappable<K<_>, T>yöntemiyle K<S> Map(Func<T, S> f)olarak uygulanması, IMappable<Option<_>, T>, IMappable<List<_>, T>. Bu yüzden bundan faydalanmak için kısıtlamanız K<T> : IMappable<K<_>, T>gerekir.
GregRos

1
Döküm uygun bir benzetme değildir. Tür sınıflarıyla (veya benzer yapılarla) yapılan, belirli bir türün daha yüksek tür türünü nasıl karşıladığını göstermenizdir. Bu genellikle yeni işlevlerin tanımlanmasını veya varolan işlevlerin (veya Scala gibi bir OO dili varsa yöntemlerin) kullanılabileceğini göstermeyi içerir. Bu yapıldıktan sonra, daha yüksek türle çalışmak üzere tanımlanan tüm işlevlerin tümü bu türle çalışır. Ancak bir arayüzden çok daha fazlasıdır, çünkü basit bir işlev / yöntem imzaları kümesinden daha fazlası tanımlanmıştır. Sanırım bunun nasıl çalıştığını göstermek için bir cevap yazmam gerekecek.
itsbruce

Yanıtlar:


5

Kimse soruyu cevaplamadığından, kendim bir deneyeceğim. Biraz felsefi olmak zorunda kalacağım.

Genel programlama, tip bilgisi kaybı olmadan (nesneye yönelik değer polimorfizmi ile ne olur) benzer türler üzerinde soyutlama ile ilgilidir. Bunu yapmak için, türlerin kullanabileceğiniz bir tür arabirimi (OO terimi değil, bir dizi işlem) paylaşması gerekir.

Nesneye yönelik dillerde, türler sınıflar sayesinde bir arayüzü tatmin eder. Her sınıfın türünün bir parçası olarak tanımlanan kendi arayüzü vardır. Tüm sınıflar List<T>aynı arabirimi paylaştığından hangisini Tseçerseniz seçin işe yarayan bir kod yazabilirsiniz . Bir arabirim dayatmanın bir başka yolu da miras kısıtlamasıdır ve ikisi farklı görünse de, bunu düşünürseniz benzerdirler.

Çoğu nesne yönelimli dilde, List<>kendi içinde uygun bir tür değildir. Herhangi bir yöntemi yoktur ve bu nedenle arayüzü yoktur. Sadece List<T>bu şeyler var. Esasen, daha teknik terimlerle, anlamlı bir şekilde soyutlayabileceğiniz türler türüne sahip olanlardır *. Nesneye yönelik bir dünyada daha yüksek türlerden yararlanmak için, tür kısıtlamalarını bu kısıtlama ile tutarlı bir şekilde ifade etmelisiniz.

Örneğin, yorumlarda belirtildiği gibi, biz görüntüleyebilir Option<>ve List<>bir işlevi varsa, "Haritalanabilir" olarak, bir anlamda, bir dönüştürmek olabilir Option<T>bir içine Option<S>veya List<T>bir içine List<S>. Sınıfların doğrudan daha üst düzey türler üzerinde soyutlamak için kullanılamayacağını hatırlayarak, bunun yerine bir arayüz oluştururuz:

IMappable<K<_>, T> where K<T> : IMappable<K<_>, T>

Sonra hem arabirimini uygulamak List<T>ve Option<T>olarak IMappable<List<_>, T>ve IMappable<Option<_>, T>sırasıyla. Gerçek (non-yüksek-kinded) türlerinde yer kısıtlamaları yüksek kinded türlerini kullanıyor Yaptığımız şey Option<T>ve List<T>. Scala'da bu şekilde yapılır, ancak Scala'nın özellikleri, tür değişkenleri ve onu daha anlamlı hale getiren örtülü parametreler gibi özellikleri vardır.

Diğer dillerde, daha yüksek türlü türleri doğrudan soyutlamak mümkündür. Yazı sistemleri ile ilgili en yüksek makamlardan biri olan Haskell'de, daha yüksek bir türe sahip olsa bile, herhangi bir tip için bir tip sınıfını ifade edebiliriz. Örneğin,

class Mappable mp where
    map :: mp a -> mp b

Bu, (tanımlanmamış) türüne doğrudan yerleştirilmiş bir kısıtlama mptek tip bir parametre alır, ve bu fonksiyon ile ilişkili gerektiren mapbir döner mp<a>bir halinde mp<b>. Daha sonra Mappable, nesne yönelimli dillerde olduğu gibi, kalıtım kısıtlaması koyabileceğiniz gibi, daha yüksek tür türlerini kısıtlayan işlevler yazabiliriz . İyi sıralama.

Özetlemek gerekirse, daha yüksek dereceli türlerden yararlanabilmeniz, onları kısıtlama veya tür kısıtlamalarının bir parçası olarak kullanma yeteneğinize bağlıdır.


İş değiştirmekle çok meşgul oldum ama sonunda kendi cevabımı yazmak için biraz zaman bulacağım. Yine de kısıtlamalar fikrinden rahatsız olduğunuzu düşünüyorum. Daha yüksek tür türlerinin önemli bir yönü, mantıksal olarak nitelendirilebildiği gösterilebilecek herhangi bir tipe uygulanabilen fonksiyonların / davranışların tanımlanmasına izin vermeleridir. Mevcut sınıflara kısıtlama getirmekten çok, yazım sınıfları (daha yüksek tür türlerinin bir uygulaması) bunlara davranış ekler.
itsbruce

Bence bu bir anlambilim meselesi. Bir tür sınıfı, bir tür sınıfı tanımlar. Gibi bir işlev tanımladığınızda , type sınıfının üyesi olmak için (Mappable mp) => mp a -> mp bbir kısıtlama mpkoydunuz Mappable. Aşağıdaki gibi bir tür ilan zaman Optionbir örneği olacak şekilde Mappable, bu tip davranış ekleyin. Sanırım bu davranışı hiçbir şekilde kısıtlamadan yerel olarak kullanabilirsiniz, ancak sıradan bir işlev tanımlamaktan farklı değildir.
GregRos

Ayrıca, tür sınıflarının doğrudan yüksek türlü türlerle doğrudan ilişkili olmadığından oldukça eminim. Scala, daha yüksek türlü türlere sahiptir, ancak tür sınıflarına sahip değildir ve tür sınıflarını, *kullanılamaz hale getirmeden türle türlerle sınırlandırabilirsiniz . Yine de, yüksek sınıf türleriyle çalışırken tip sınıflarının çok güçlü olduğu kesinlikle doğrudur.
GregRos

Scala'nın tip sınıfları var. Bunlar imalarla uygulanır. Çıkarımlar Haskell tipi sınıf örneklerinin eşdeğerini sağlar. Haskell'den daha kırılgan bir uygulama çünkü bunun için özel bir sözdizimi yok. Ama her zaman Scala imalarının temel amaçlarından biriydi ve işi yapıyorlar.
itsbruce
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.