Groovy'nin uygulaması curryaslında hiçbir noktada, perde arkasında bile köri yapmaz. Kısmi uygulama ile özdeştir.
curry, rcurryVe ncurryyöntem , bir geri CurriedClosurenesne bağlı argümanlar tutar. Ayrıca getUncurriedArguments, bağlı bağımsız değişkenlerle kendisine iletilen bağımsız değişkenlerin kompozisyonunu döndüren bir yöntem (yanlış adlandırılmış - işlevleri bozarsınız, bağımsız değişkenleri değil).
Bir kapatma çağrıldığında, sonuçta çağıran nesnenin bir örneği olup olmadığını açıkça kontrol eden invokeMethodyönteminiMetaClassImpl çağırır CurriedClosure. Öyleyse, yukarıda belirtilenleri getUncurriedArgumentsuygulamak için tüm argüman dizisini oluşturmak için kullanır :
if (objectClass == CurriedClosure.class) {
// ...
final Object[] curriedArguments = cc.getUncurriedArguments(arguments);
// [Ed: Yes, you read that right, curried = uncurried. :) ]
// ...
return ownerMetaClass.invokeMethod(owner, methodName, curriedArguments);
}
Yukarıdaki kafa karıştırıcı ve biraz tutarsız bir isimlendirmeye dayanarak, bunu yazan her kimsenin iyi bir kavramsal anlayışa sahip olduğundan şüpheleniyorum, ama belki biraz aceleci ve - birçok akıllı insan gibi - kısmi uygulama ile körelemeyi sınırladı. Biraz talihsiz ise bu anlaşılabilir (Paul King'in cevabına bakınız); geriye dönük uyumluluğu bozmadan bunu düzeltmek zor olacaktır.
Önerdiğim bir çözümcurry , herhangi bir argüman iletilmediğinde, gerçek körelme yapacak şekilde yöntemin aşırı yüklenmesi ve yöntemin yeni bir partialişlev lehine argümanlarla çağrılmasının kaldırılmasıdır . Bu biraz garip gelebilir , ancak sıfır argümanla kısmi uygulama kullanmak için bir sebep olmadığından geriye dönük uyumluluğu en üst düzeye çıkarırken, işlev aslında gerçek körelme için yeni, farklı adlandırılmış bir işleve sahip olmanın (IMHO) çirkin durumundan kaçınırken adlı curryfarklı ve kafa karıştırıcı bir şey yapar.
Arama sonucunun currygerçek körelemeden tamamen farklı olduğunu söylemeye gerek yok . İşlevi gerçekten köreltiyorsa, şunları yazabilirsiniz:
def add = { x, y -> x + y }
def addCurried = add.curry() // should work like { x -> { y -> x + y } }
def add1 = addCurried(1) // should work like { y -> 1 + y }
assert add1(1) == 2
Çünkü ... ve o çalışacak addCurriedgibi çalışması gerekir{ x -> { y -> x + y } } . Bunun yerine bir çalışma zamanı istisnası atar ve içinde biraz ölürsün.