2011-06-25 20 views
6

Scala'yı öğrenme konusundaki çabalarım boyunca, Odersky tarafından 'örnekle Scala' üzerinden çalışıyorum ve birinci sınıf işlevler bölümünde, anonim işlevle ilgili bölüm, yinelemeli anonim işlevlerden kaçınıyor. Çalıştığım bir çözüm var. Orada daha iyi bir cevap varsa merak ediyorum. Code yüksek mertebeden fonksiyonlar pdf den Yinelemeli anonim işlevleri nasıl yazarım?

def sum(f: Int => Int, a: Int, b: Int): Int = 
    if (a > b) 0 else f(a) + sum(f, a + 1, b) 

def id(x: Int): Int = x 
def square(x: Int): Int = x * x 
def powerOfTwo(x: Int): Int = if (x == 0) 1 else 2 * powerOfTwo(x-1) 

def sumInts(a: Int, b: Int): Int = sum(id, a, b) 
def sumSquares(a: Int, b: Int): Int = sum(square, a, b) 
def sumPowersOfTwo(a: Int, b: Int): Int = sum(powerOfTwo, a, b) 

scala> sumPowersOfTwo(2,3) 
res0: Int = 12 

vitrin:

def sumPowersOfTwo(a: Int, b: Int): Int = sum((x: Int) => { 
    def f(y:Int):Int = if (y==0) 1 else 2 * f(y-1); f(x) }, a, b) 

scala> sumPowersOfTwo(2,3) 
res0: Int = 12 
+0

Bundan emin misiniz? echo "2^2 + 3^2" | bc -l' -> 13'. – sarnold

+0

Bu bir kopya http://stackoverflow.com/questions/5337464/anonymous-recursive-function-in-scala – Suroot

+1

@sarnold İki Güçlerin Toplamı - yani '2^a + 2^a + 1 + ... 2^b-1 + 2^b '2^2 + 2^3 = 4 + 8 = 12' –

cevap

13

için: anonim fonksiyonları

def sum(f: Int => Int, a: Int, b: Int): Int = 
    if (a > b) 0 else f(a) + sum(f, a + 1, b) 

def sumInts(a: Int, b: Int): Int = sum((x: Int) => x, a, b) 
def sumSquares(a: Int, b: Int): Int = sum((x: Int) => x * x, a, b) 
// no sumPowersOfTwo 

Kodum vitrin Kod pdf itibaren

ne değerse ... (başlık ve "gerçek soru" oldukça yok

Recursive anonim işlev-nesneler FunctionN ve sonra apply içindeki this(...) kullanmanın uzanan "Uzun yandan" yoluyla oluşturulabilir) katılıyorum. Bununla birlikte, bu genellikle ortaya çıkarılan yapışkanlık miktarı, yaklaşımın genellikle idealden daha az olmasını sağlar. En iyi sadece bir "ad" kullanın ve biraz daha açıklayıcı, modüler kod var - Aşağıdaki böyle ;-)

val printingCounter: (Int) => Unit = (x: Int) => { 
    println("" + x) 
    if (x > 1) printingCounter(x - 1) 
} 
printingCounter(10) 

Mutlu kodlama için çok iyi bir argüman değil o.

2

Sen bu dolaylı özyinelemeye genelleme yapabiliriz:

case class Rec[I, O](fn : (I => O, I) => O) extends (I => O) { 
    def apply(v : I) = fn(this, v) 
} 

Şimdi toplamı gibi dolaylı özyineleme kullanarak yazılabilir: Aynı çözüm örneğin Memoization uygulamak için kullanılabilir

val sum = Rec[Int, Int]((f, v) => if (v == 0) 0 else v + f(v - 1)) 

.

İlgili konular