2014-06-11 3 views
18

इस सरल currying समारोह को देखते हुए:क्यों करीबी कार्यों को बाहरी पैरामीटर नामों की आवश्यकता होती है?

func foo(x:Int)(y:Int)->String{ 
    return "\(x) with \(y)" 
} 

मैं इस तरह कुछ करने के लिए सक्षम होने के लिए उम्मीद थी:

let bar = foo(1) 
bar(2) //<- error: Missing argument label 'y:' in call 

अगर मैं bar करने के लिए कॉल लेबल (bar(y:2) के रूप में) सब कुछ ठीक काम करता है । लेकिन मुझे समझ में नहीं आता कि पैरामीटर नाम क्यों जरूरी है। क्या इससे बचने का कोई तरीका है?

स्पष्ट बात:

func foo(x:Int)(_ y:Int)->String ...

काम करने के लिए प्रतीत नहीं होता।

+3

अच्छा! यह मुद्दा दोनों शीर्ष-स्तरीय func और क्लास विधि के लिए मौजूद है। – GoZoner

+0

हाँ; स्विफ्ट पुस्तक में घुमाने का उदाहरण भी दिखाता है (इसे पेस्ट करें, दूसरा "मैन्युअल" करीकरण फ़ंक्शन हटाएं, और आप "गायब तर्क लेबल 'बी प्राप्त करें:' कॉल में") –

+0

इसे rdar के रूप में लिखा: // 17359591। कृपया डुप्लीकेट करने के लिए स्वतंत्र महसूस करें। – jemmons

उत्तर

0

मुझे यकीन है कि नहीं मैं पूरी तरह से अपने currying समझ में हूँ। यहां मेरा लेना है।

func foo(x:Int, y:Int) -> String{ 
    return "\(x) with \(y)" 
} 

let bar = foo(1, 2) // gives "1 with 2" 

मैं इस प्रकार है 'फिक्स' x के लिए मूल्य को यह समारोह करी, इसलिए ऐसा करना चाहते:: मैं एक समारोह foo के रूप में निम्नानुसार है

func fooCurry(x:Int) -> (Int -> String) { 
    func curry(y:Int) -> String { 
    return foo(x, y) 
    } 
    return curry 
} 

ऊपर रिटर्न एक नया कार्य जो इस प्रकार के रूप में इस्तेमाल किया जा सकता है:

let curriedFoo = fooCurry(1) 
let barWithCurry = curriedFoo(2) // gives "1 with 2" 

समारोह fooCurry द्वारा लौटाए गए हस्ताक्षर (Int -> String), जिसका अर्थ है कि पैरामीटर एक बाह्य नहीं है है एल नाम

+3

आप क्या ' यहाँ फिर से मूल रूप से 'हाथ से' घुमा रहा है। 'func foo (x: int) (y: int) -> स्ट्रिंग' को भाषा सुविधा के रूप में बॉक्स से बाहर काम करना चाहिए, और ऐसा नहीं है। –

1

मेरा मानना ​​है कि यह एक संकलक बग है, अपने उदाहरण स्विफ्ट प्रोग्रामिंग भाषा पुस्तक जहां वे curried कार्यों की घोषणा का उल्लेख में वर्णित के रूप में काम करना चाहिए:

func addTwoNumbers(a: Int)(b: Int) -> Int { 
    return a + b 
} 

addTwoNumbers(4)(5) // Returns 9 

https://bugreport.apple.com

अच्छा लगता है!

8

यह एक बग, आप एक रडार bugreport.apple.com

पुष्टि के रूप में, यह

func foo(x: Int)(_ y: Int) -> String 

आप एक चेतावनी

वाले अप्रासंगिक 'प्राप्त की तरह दर्ज करनी चाहिए है अगर आप एक अंडरस्कोर जगह, _ 'पैरामीटर में:' y 'से कोई भी कीवर्ड तर्क नाम है

तो यह स्पष्ट रूप से कहता है कि y का कोई बाहरी नाम नहीं है, लेकिन इसे अभी भी कॉल करने की आवश्यकता होती है, जो स्पष्ट रूप से भाषा विनिर्देश के खिलाफ है।

0

सर्वश्रेष्ठ नहीं है वाक्य रचना, लेकिन अब आप के लिए इसके चारों ओर पाने के लिए चाहते हैं, तो आपको निम्न बुनियादी curried कार्यों के लिए उपयोग कर सकते हैं:

func foo(x:Int) -> Int -> String { 
    return { 
    return "\(x) with \($0)" 
    } 
} 

तो फिर तुम सिर्फ कर सकते हैं:

let bar = foo(1) 
bar(2) //-> 1 with 2 

अब स्पष्ट रूप से यह समस्या स्पष्ट हो जाती है जब आप चार Int एस पाइपिंग के लिए एक करीबी फ़ंक्शन लिखना चाहते हैं उदाहरण के लिए:

func makerAdders(a:Int)(b:Int)(c:Int)(d:Int) {...} 

इस तरह हो जाता है:

func add(a:Int) -> Int -> Int -> Int -> Int { 
    return { 
    b in return { 
     c in return { 
     d in return a + b + c + d 
     } 
    } 
    } 
} 

भीतरी बंद यह थोड़ा भीतरी कार्यों का उपयोग कर की तुलना में बेहतर है, लेकिन फिर से यह अच्छा func add(a:Int)(b:Int)(c:Int)(d:Int) {return a+b+c+d} वाक्य रचना के उद्देश्य को हरा दिया।

0

निश्चित रूप से संकलक में एक बग जहां तक ​​मैं कह सकता हूं। जब तक यह आप इन कार्यों का उपयोग कर किसी भी समारोह के एक ठीक से curried संस्करण प्राप्त कर सकते निश्चित होती है (ध्यान दें कि मैं दो और तीन तर्क के लिए मामलों को शामिल किया है, अपने खाली समय में विस्तार:

func curry<A,B,C>(f: (A, B) -> C) -> A -> B -> C { 
    return { a in { b in return f(a,b) } } 
} 

func curry<A,B,C,D>(f: (A, B, C) -> D) -> A -> B -> C -> D { 
    return { a in { b in { c in return f(a,b,c) } } } 
} 

बस का उपयोग करें:

curry(addTwoNumbers)(1)(2) 
संबंधित मुद्दे

 संबंधित मुद्दे