การนำไปใช้ของ Groovy curry
ไม่ได้เกิดขึ้นจริงในทุกช่วงเวลาแม้แต่หลังฉาก มันเป็นหลักเหมือนกับการประยุกต์ใช้บางส่วน
curry
, rcurry
และncurry
วิธีการส่งคืนCurriedClosure
วัตถุที่มีข้อโต้แย้งที่ถูกผูกไว้ นอกจากนี้ยังมีวิธีการgetUncurriedArguments
(ฟังผิด - คุณแกงฟังก์ชั่นไม่ขัดแย้ง) ซึ่งส่งกลับองค์ประกอบของข้อโต้แย้งที่ส่งผ่านไปยังมันด้วยข้อโต้แย้งที่ถูกผูกไว้
เมื่อมีการปิดรับการเรียกว่าในท้ายที่สุดมันเรียกวิธีการที่ชัดเจนตรวจสอบเพื่อดูว่าวัตถุที่เรียกเป็นตัวอย่างของ ถ้าเป็นเช่นนั้นจะใช้การดังกล่าวข้างต้นเพื่อเขียนอาเรย์เต็มรูปแบบของการขัดแย้งที่จะนำไปใช้:invokeMethod
MetaClassImpl
CurriedClosure
getUncurriedArguments
if (objectClass == CurriedClosure.class) {
// ...
final Object[] curriedArguments = cc.getUncurriedArguments(arguments);
// [Ed: Yes, you read that right, curried = uncurried. :) ]
// ...
return ownerMetaClass.invokeMethod(owner, methodName, curriedArguments);
}
จากการตั้งชื่อที่สับสนและไม่สอดคล้องกันข้างต้นฉันสงสัยว่าใครก็ตามที่เขียนสิ่งนี้มีความเข้าใจในแนวคิดที่ดี แต่อาจจะรีบหน่อยและเหมือนคนฉลาด ๆ หลายคน นี่เป็นสิ่งที่เข้าใจได้ (ดูคำตอบของพอลคิง) หากโชคร้ายเล็กน้อย มันจะยากที่จะแก้ไขโดยไม่ทำลายความเข้ากันได้ย้อนหลัง
ทางออกหนึ่งที่ฉันแนะนำคือการโอเวอร์โหลดcurry
เมธอดดังกล่าวเมื่อไม่มีการส่งผ่านข้อโต้แย้งมันจะเป็นการแก้ปัญหาจริงและเลิกเรียกวิธีที่มีข้อโต้แย้งเพื่อสนับสนุนpartial
ฟังก์ชันใหม่ สิ่งนี้อาจดูแปลกไปเล็กน้อยแต่มันจะเพิ่มความเข้ากันได้ย้อนหลัง - เนื่องจากไม่มีเหตุผลที่จะใช้แอพพลิเคชั่นบางส่วนที่มีข้อโต้แย้งที่เป็นศูนย์ - ในขณะที่หลีกเลี่ยงสถานการณ์ที่ไม่ดี (IMHO) ชื่อcurry
ทำสิ่งที่แตกต่างและคล้ายกันอย่างสับสน
มันไปโดยไม่บอกว่าผลลัพธ์ของการโทรcurry
นั้นแตกต่างจากการแกงจริงอย่างสิ้นเชิง หากฟังก์ชั่น curry จริงๆคุณจะสามารถเขียน:
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
... และมันก็ใช้ได้เพราะaddCurried
ควรทำเช่น{ x -> { y -> x + y } }
นั้น แต่มันเป็นข้อยกเว้นรันไทม์และคุณตายภายในเล็กน้อย