2015-08-25 22 views
7

Burada, örtük bir yeniden sıralama dönüşümü ile birlikte gelen "değişimli" bir çift türü tanımladığım basit bir çoğaltıcıdır. Örtük dönüşüm, f işlevi için argüman önceden varolan bir adlandırılmış değerde (örnekte t) varsa, derleyici tarafından beklendiği gibi uygulanır. Ancak, f doğrudan literal CommutativePair numaralı telefondan aramayı denerseniz, bir tür hatasıyla başarısız olur. Derleyici, bu durumda örtük yeniden sıralama dönüşümünü uygulamıyor.Scala örtülü dönüştürme bazı koşullar altında uygulanmaktadır, ancak diğerleri değil

object repro { 
    import scala.language.implicitConversions 

    case class CommutativePair[A, B](a: A, b: B) 

    object CommutativePair { 
    // Support a kind of commutative behavior via an implicit reordering 
    implicit def reorderPair[B, A](pair: CommutativePair[B, A]) = 
     CommutativePair(pair.b, pair.a) 
    } 

    // The idea is to allow a call to 'f' with Pair[Int, String] as well, 
    // via implicit reorder. 
    def f(p: CommutativePair[String, Int]) = p.toString 

    val t = CommutativePair(3, "c") 

    // This works: the implicit reordering is applied 
    val r1 = f(t) 

    // This fails to compile: the implicit reordering is ignored by the compiler 
    val r2 = f(CommutativePair(3, "c")) 
} 
+0

Tür çıkarımı başarısız gibi görünüyor; CommutativePair'e [Int, String] eklediğinizde tekrar derler. –

+0

@LodewijkBogaards, kabul etti, bir scala derleyici hata olarak rapor etmeyi düşünüyorum, ama ne tür cevaplar aldığımı görmeyi bekliyorum. – eje

+0

Yapmalısınız. Kodunu 2.11.7'de çalıştırdım ve aynı problemi aldım. Derleyicinin bununla uğraştığını hayal edebilirsem de işe yaramalı. –

cevap

2

buna çözüm ararken sıraya tetiklediği scala çıkarsama sınırı, isabet inanıyoruz. İlk durumda: Bu parametrelere dayalı çalışır tek kişi olduğu için

val t = CommutativePair(3, "c") 

çıkarsama, CommutativePair[Int,String] türünü kilitledi. Bu yüzden aradığında: Bu Commutative[Int,String] = = Commutative[String,Int], o zaman implicits arar bir tür uyuşmazlığı alır ve üst üste bulduğu

val r1 = f(t) 

. İkinci durumda

, scala dışarıdan yolunda çalışan türlerini anlamaya çalışıyor:

val r2 = f(CommutativePair(3, "c")) 
  • Birincisi, f, Commutative[String,Int] alması gerektiğini belirler. Daha sonra, CommutativePair(...,...)'un Commutative[String,Int] olması gerekir (çünkü bu, parametresinden türünün türünü belirleyememiştir).
  • Şimdi parametrelere CommutativePair(...)'a bakar ve yanlış türde olmalarını bulur. Ancak bu, örtük dönüştürme işlemini tetiklemez çünkü tüm uyumsuzlukların parametreler içinde olduğunu düşünür, CommutativePair(...).

Gerçekten de, tür params kilitleme (açıkça veya bir val ilk önce bağlayarak), hatayı giderir.

İlgili konular