2015-02-11 7 views
7

Herhangi bir örtülü dönüştürme ve daha yüksek işlevli işlev sorunum var. Bir fonksiyonun bir ikinci-sıra-fonksiyonuna dolaylı bir dönüşümünün, dönüştürülecek işlevin en az iki parametresi olması durumunda, işe yarayacağı görülmektedir.Bir işlevin bir ikinci-sıra-işlevine örtük dönüştürülmesi, yalnızca dönüştürülecek işlev en az iki parametreye sahipse çalışır.

İşleri:

implicit def conv(foo: Integer => String): String => String = null 

Çalışmaz:

implicit def conv(foo: Integer => String): String => String => String = null 

Çalışır:

{ 
    implicit def conv(foo: Integer => String): String => String = null 

    def baadf00d(foo: Integer): String = null 

    def deadbeef(foo: String => String) = null 

    deadbeef(conv(baadf00d)) 

    deadbeef(baadf00d) 
} 

{ 
    implicit def conv(foo: Integer => String): String => String => String = null 

    def baadf00d(foo: Integer): String = null 

    def deadbeef(foo: String => String => String) = null 

    deadbeef(conv(baadf00d)) 

    deadbeef(baadf00d) // <-------- DOES NOT COMPILE! 
} 

{ 
    implicit def conv(foo: (Integer, Integer) => String): String => String => String = null 

    def baadf00d(foo: Integer, bar: Integer): String = null 

    def deadbeef(foo: String => String => String) = null 

    deadbeef(conv(baadf00d)) 

    deadbeef(baadf00d) 
} 
: başarısızlık noktası ile

implicit def conv(foo: (Integer, Integer) => String): String => String => String = null 

Tam örneği

Neyi özlüyorum?

Teşekkürler!

+2

bana Scala örtük bir çözünürlük siğil gibi görünüyor. Hangi Scala sürümü bu? – gzm0

cevap

-1
implicit def conv1(a: Function1[Int, String]): Function2[String, String, String] = null 
def baadf00d1(i: Int): String = null 
def deadbeef1(arg: Function2[String, String, String]) = null 
deadbeef(baadf00d) // compiles 

O olmuyor A => B ve Function1[A,B] arasında dönüşüm bu.

Ayrıca Predef bir Function tipi vardır - burada tip farklılıkları dikkat edin: (yorum aşağıda da belirtildiği gibi)

scala> val f1: Function[Int, Int] = null 
f1: Function[Int,Int] = null 

scala> val f2: Function1[Int, Int] = null 
f2: Int => Int = null 

scala> :type f1 
Function[Int,Int] 

scala> :type f2 
Int => Int 

O Function1 bir takma, ama farklı tip sınırları ile. örtük dönüşümler Scala ve Scala Körili ve uncurried fonksiyonlar olduğu gerçeği üzerinde çalışmak nasıl

+0

Veya 'val baadf00d2 = baadf00d _' kullanarak bir baara 'baadf00d' atayabilirsiniz ve daha sonra –

+0

çalışır: yazın ve: REPL içinde onları düzgün bir şekilde davranın ve daha da garip görünmesini sağlayın. –

+2

Predef.scala'dan "type İşlevi [-A, + B] = İşlev1 [A, B]" – zarthross

3
implicit def conv(foo: Integer => String): String => String => String = ??? 

    def baadf00d(i: Integer): String = ??? 
    def goodf00d: Integer => String = _ => ??? 

    def deadbeef(foo: String => String => String) = ??? 

    deadbeef(conv(baadf00d)) 

    deadbeef(baadf00d) // <-------- DOES NOT COMPILE! 
    deadbeef(goodf00d) // <-------- COMPILE! 
    // ¯\_(ツ)_/¯ 

konudur.

Bu, İŞLETMESİ GEREKMEKTEDİ, ancak muhtemelen başka bir derleyici hatasının bulunmadığı bir şeydir (Scala'yı kullandığınızda çok daha fazlasını karşılamaya hazır olun).

DÜZENLEME: En son örnekte fonksiyon tanımları maçı var çünkü var

implicit def conv(foo: (Integer, Integer) => String): String => String => String = null 

def baadf00d(foo: Integer, bar: Integer): String = null 

def deadbeef(foo: String => String => String) = null 

gelince. Konv, (Int, Int) => String numaralı bir işlevi ve baadf00d'un nasıl tanımlandığı gibi, scala'daki normal bir yöntem tanımlaması bekler.

Örneğin bir işlevi:

def f(a: Int, b: Int): String 

2 Ints tupled olduğu bir

(Int, Int) => String 

Bildirimi dönüştü alır! Eğer içine baadf00d yeniden tanımlamak için

Int => Int => String 

olsaydı:

def baadf00d: Integer => Integer => String = _ => _ => ??? 

Bu kod derlemek olmaz baadf00d şimdi "farklı" olduğu için yapıyor olsa bile, aynı Bu aynı değildir aynı şey.Daha fazla bilgi için

, nesnelerin tanımı bakmak:

Function1, Function2, Function3 .... 

http://www.scala-lang.org/api/current/#scala.Function2

+0

Tamam, bu yüzden ikinci dönüşümün çalışmadığı neden sadece derleyici bir hatadan kaynaklanıyor ... – user3612643

+0

Yep. Scala'da, 'baadf00d' ve' goodf00d' '(Int) => String' ve' Int => String’e özel olarak dönmelidir. Şimdi bu şeyler aynı olmalı, ancak bir nedenden dolayı, örtülü çözüm onların farklı olduklarını düşünüyor. '' Baadf00d''yi '' conv''na aktarabilmeniz gerçeği, aynı olduklarını kanıtlar, sadece örtük bir çözüm, bunu anlamak için çok aptaldır. – Nacht

İlgili konular