2011-06-13 23 views
22

Daha önce başka bir yerde sorulmuşsa beni affet. İşlev değerleri ve örtük parametreler içeren bir Scala sözdizimi sorusu var.Scala Implicits Fonksiyonel Literallar

Scala'nın köreltme özelliği ile dolaylı sonuçları kullanıyorum. Mesela ben bir toplamı işlevi vardı ve örtük bir ikinci argüman yapmak istiyorsa:

scala> def sum(a: Int)(implicit b: Int) = a + b 
sum: (a: Int)(implicit b: Int)Int 

fonksiyon değeri sözdizimini kullanarak bunu yapmanın bir yolu var mı? Bir an için kapalı dikkate alınmadığında, I, tipik olarak, bu gibi curried fonksiyon değerlerini geç

scala> val sum2 = (a: Int) => (b: Int) => a + b 
sum: (Int) => (Int) => Int = <function1> 

Bununla birlikte, ikinci yaklaşımda işlev imzası çok farklı (tımar açıkça ifade ediliyor) 'dir. Sadece çok mantıklı değil b örtülü anahtar kelime ekleyerek ve derleyici yanı yakınır:

scala> val sum2 = (a: Int) => (implicit b: Int) => a + b 
<console>:1: error: '=>' expected but ')' found. 
     val sum2 = (a: Int) => (implicit b: Int) => a + b 
              ^

Ayrıca bir işlev değeri de sorunlara neden olmaktadır almak çok birinci yaklaşımından toplamını kısmen uygulanması:

scala> val sumFunction = sum _ 
<console>:14: error: could not find implicit value for parameter b: Int 
     val sumFunction = sum _ 
         ^

Bu, örtük parametrelere sahip işlevlerin, işlev değeri daha sonra uygulandığında değil, işlev değeri oluşturulduğunda belirtilen parametrelere sahip olması gerektiğine inanmamı sağlar. Bu gerçekten böyle mi? İşlev değeri olan örtülü bir parametre kullanabilir misiniz?

Yardımın için teşekkürler!

+0

Ne yazık ki, sizin için bir cevap yok, ama açıklayıcı sorum var: İkinci paragrafta bir 'sum' * fonksiyonu * bahsetmek ancak karşılık gelen kod örneği' sum' gösterir *yöntem*. Hangisini demek istiyorsun? –

+0

Merhaba Jörg - Anlayışım, bir metodun sadece bir sınıf veya nesne ile ilişkilendirilmiş bir işlev olmasıdır. Yukarıdaki tüm fonksiyonlar Scala REPL içine yazılmıştır; kullanıcı tanımlı sınıf veya nesne oluşturulmadı. Yani sadece burada fonksiyonlarla uğraştığımızı söyleyebilirim. – shj

cevap

16
scala> val sum2 = (a: Int) => {implicit b: Int => a + b} 
sum2: (Int) => (Int) => Int = <function1> 

Bu sadece fonksiyon gövdesinin kapsamı için örtük bir değere b yapacak, bu nedenle örtülü bir Int bekliyoruz yöntemleri çağırabilir.

İşlevler için örtülü argümanlara sahip olabileceğinizi sanmıyorum çünkü o zaman işlevin ne olduğu açık değil. Int => Int veya () => Int mu?

buldum yakın

olup: sum2 kesin türü Function1[Int, Function1[Int, Int]] olduğu bu pasajı olarak

scala> case class Foo(implicit b: Int) extends (Int => Int) {def apply(a: Int) = a + b} 
defined class Foo 

scala> implicit val b = 3 
b: Int = 3 

scala> Foo() 
res22: Foo = <function1> 

scala> res22(2) 
res23: Int = 5 
9

scala> val sum2 = (a: Int) => (b: Int) => a + b 
sum: (Int) => (Int) => Int = <function1> 

not edin. Eğer b örtülü yapmaya çalışırsanız Ayrıca, Şimdi

val sum2 = new Function1[Int, Function1[Int, Int]] { 
    def apply(a: Int) = new Function1[Int, Int] { 
     def apply(b: Int) = a + b 
    } 
} 

olarak yazılmış olabilir, bu olsun: başka bir deyişle,

scala>  val sum2 = new Function1[Int, Function1[Int, Int]] { 
    |   def apply(a: Int) = new Function1[Int, Int] { 
    |    def apply(implicit b: Int) = a + b 
    |   } 
    |  } 
<console>:8: error: object creation impossible, since method apply in trait Function1 of type (v1: Int)Int is not defined 
       def apply(a: Int) = new Function1[Int, Int] { 
            ^

Veya Function 'ın arayüzleri, örtülü parametreleri yok dolaylı bir parametre ile her şey Function değildir.

3

Başvuru yöntemini aşırı yüklemeyi deneyin.

scala> val sum = new Function1[Int, Function1[Int, Int]] { 
     |  def apply(a: Int) = (b: Int) => a + b 
     |  def apply(a: Int)(implicit b: Int) = a + b 
     |} 
sum: java.lang.Object with (Int) => (Int) => Int{def apply(a:Int)(implicit b: Int): Int} = <function1> 

scala> sum(2)(3) 
res0: Int = 5 

scala> implicit val b = 10 
b: Int = 10 

scala> sum(2) 
res1: Int = 12