Plasty Grove tarafından bağlanılan cevapta semantik farklılık oldukça iyi açıklanmıştır .
İşlevsellik açısından, yine de pek bir fark görünmüyor. Bunu doğrulamak için bazı örneklere bakalım. İlk olarak, normal bir işlev:
scala> def modN(n: Int, x: Int): Boolean = ((x % n) == 0)
scala> modN(5, _ : Int)
res0: Int => Boolean = <function1>
Böylece <function1>
, an alan bir kısmen uygulanmış Int
oluyoruz, çünkü ona zaten ilk tamsayıyı verdik. Çok uzak çok iyi. Şimdi köriye:
scala> def modNCurried(n: Int)(x: Int): Boolean = ((x % n) == 0)
Bu gösterimle, safça aşağıdakilerin işe yaramasını beklersiniz:
scala> modNCurried(5)
<console>:9: error: missing arguments for method modN;
follow this method with `_' if you want to treat it as a partially applied function
modNCurried(5)
Dolayısıyla, çoklu parametreli liste gösterimi gerçekten hemen curried bir işlev yaratmıyor gibi görünüyor (varsayım gereği gereksiz ek yükten kaçınmak için), ancak curried yapmak istediğinizi açıkça belirtmenizi bekler (gösterimin başka avantajları da vardır):
scala> modNCurried(5) _
res24: Int => Boolean = <function1>
Bu, daha önce sahip olduğumuz şeyin tam olarak aynısı, yani burada gösterim dışında hiçbir fark yok. Başka bir örnek:
scala> modN _
res35: (Int, Int) => Boolean = <function2>
scala> modNCurried _
res36: Int => (Int => Boolean) = <function1>
Bu, "normal" bir işlevin kısmen uygulanmasının tüm parametreleri alan bir işlevle sonuçlandığını gösterirken, birden çok parametre listesiyle bir işlevi kısmen uygulamak, her parametre listesi için bir işlev zinciri oluşturan ve tümü yeni bir işlev döndüren bir işlev zinciri oluşturduğunu gösterir :
scala> def foo(a:Int, b:Int)(x:Int)(y:Int): Int = a * b + x - y
scala> foo _
res42: (Int, Int) => Int => (Int => Int) = <function2>
scala> res42(5)
<console>:10: error: not enough arguments for method apply: (v1: Int, v2: Int)Int => (Int => Int) in trait Function2.
Unspecified value parameter v2.
Gördüğünüz gibi, ilk parametre listesi foo
iki parametreye sahip olduğu için, kıvrımlı zincirdeki ilk işlevin iki parametresi vardır.
Özetle, kısmen uygulanan işlevler, işlevsellik açısından gerçekten farklı biçimlerde kıvrımlı işlevler değildir. Bu, herhangi bir işlevi curried olana dönüştürebileceğiniz için kolayca doğrulanabilir:
scala> (modN _).curried
res45: Int => (Int => Boolean) = <function1
scala> modNCurried _
res46: Int => (Int => Boolean) = <function1>
Yazı Yazısı
Not:println(filter(nums, modN(2))
Örneğinizin alt çizgi olmadan çalışmasının nedeni modN(2)
, Scala derleyicisinin alt çizginin programcı için bir kolaylık olduğunu varsaymasıdır.
Ekleme: @asflierl'in doğru bir şekilde işaret ettiği gibi, Scala "normal" işlevleri kısmen uygularken türü çıkaramıyor gibi görünüyor:
scala> modN(5, _)
<console>:9: error: missing parameter type for expanded function ((x$1) => modN(5, x$1))
Bu bilgi, birden çok parametre listesi gösterimi kullanılarak yazılan işlevler için mevcutken:
scala> modNCurried(5) _
res3: Int => Boolean = <function1>
Bu cevaplar bunun nasıl çok faydalı olabileceğini gösteriyor.