Haskell neden monomorfizm kısıtlaması olmadan tekrarlanan değerlendirmeden kaçınamıyor?


14

Geçen gün learnyouahaskell'i yeni bitirdim ve Haskell Wiki tarafından tarif edildiği gibi Monomorfizm Kısıtlamasını anlamaya çalışıyordum . MR'nin tekrarlanan değerlendirmeleri nasıl önleyebileceğini anladığımı düşünüyorum, ancak tekrarlanan bu değerlendirmelerin neden daha basit yollarla önlenemediğini göremiyorum.

Aklımdaki belirli örnek wiki tarafından kullanılan örnek:

f xs = (len,len)
  where
    len = genericLength xs

genericLengthtürü nerede Num a => [b] -> a.

Açıkçası, değerlendirmek için genericLength xssadece bir kez hesaplanması gerekir (len,len), çünkü aynı argümanlarla aynı işlevdir. Bunu fbilmek için herhangi bir çağrıyı görmemize gerek yok . Peki Haskell neden MR gibi bir kural getirmeden bu optimizasyonu yapamıyor?

Bu wiki sayfasındaki tartışma bana bunun Numsomut bir tipten ziyade bir daktilo sınıfı olduğu gerçeği ile ilgisi olduğunu söylüyor, ancak öyle olsa bile, derleme zamanında saf bir fonksiyonun aynı değeri döndüreceği açık olmamalı- -ve böylece aynı somut Num tipi - aynı argümanlar iki kez verildiğinde?

Yanıtlar:


11

Aynı işlev adı ile aynı işlev adı, ancak potansiyel olarak farklı dönüş türleri ve uygulamaları, çünkü polimorfik. Bir bekliyor bir bağlamda deniyor eğer vasıtası O (Int, MyWeirdCustomNumType)dönüş türü, bu uygulama nedeniyle, iki kez değerlendirmek zorundadır (+)içinde Intuygulanması tamamen farklıdır (+)içinde MyWeirdCustomNumType. Bir noktada fiziksel olarak farklı kod çalıştırmanız gerekir.

Bu yüzden önemli Numbir sınıf. Farklı türler için farklı uygulamalarınız olduğu anlamına gelir. Aynı zamanda fbir kütüphanedeyse, derleme zamanında geri dönmesi gerekebilecek tüm tür kombinasyonları hakkında bilgi sahibi olmadığı anlamına gelir .

Yani, evet, fhangi dönüş türlerinin kullanılacağını bilmek için çağrıları görmeniz gerekir . Çoğu zaman, onların aynı olmasını beklersiniz, bu yüzden monomorfizm kısıtlamasını varsayılan olarak koyarlar. Yapmadığınız nadir durumlar için kapatılabilir. Uygulamada, programcılar bu tür durumları yine de tür çıkarımına kadar bırakma eğiliminde değildir.


Ben olasılığını düşünmemiştim f [] :: (Int, Float). Şimdi çok mantıklı. Teşekkür ederim.
Ixrec

1
It's the same function name, with the same arguments, but potentially different return types and implementations, because it's polymorphic.Ona bakmanın en iyi yolu, typeclass örneğinin etkili bir şekilde ekstra bir argüman olduğunu genericLengthve derleyicinin her iki çağrıda da aynı argüman olduğuna ikna olmadığını düşünüyorum.
Doval

Hızlı soru. MonomorphismRestriction kapalıdır, ancak daha sonra size böyle bir şey olmadıysa a = uncurry (==) $ f [1, 2, 3]bunun sadece kontrol uzunluğuna o çağrı sitesini optimize edebilmek olmazdı, [1, 2, 3]bir kere? Eğer öyleyse, o zaman monomorfizm kısıtlamasının sizi gerçekten satın aldığı konusunda gerçekten kafam karıştı, eğer değilse neden olmasın?
noktalı virgül
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.