2011-06-24 18 views
13

मैं एफ # प्रकार हस्ताक्षर नोटेशन के साथ संघर्ष कर रहा हूं। उदाहरण के लिए मान लीजिए कि आप एक फोल्ड कार्य हो जाने:एफ # प्रकार हस्ताक्षर कैसे पढ़ा जाए?

let rec Fold combine acc l = 
... 

कि इस प्रकार के हस्ताक्षर हो सकता है:

('a -> 'b -> 'a) -> 'a -> list<'b> -> 'a 

जो मैं के रूप में

पढ़ें एक समारोह तीन तर्क हैं कि:

  • एक ऐसा कार्य जो 'ए' लेता है, एक
  • एक ख

'एक

  • एक की सूची' 'ख और एक एक रिटर्न' और एक 'एक देता है।

    लेकिन फिर इसे और अधिक समझ में मेरी cavemen के मस्तिष्क के रूप में

    ('a, 'b -> 'a), 'a, list<'b> -> 'a 
    

    यह व्यक्त करने के लिए मुझे यकीन है कि वहाँ एक अर्थ कारण है कि मानकों समारोह के रूप में एक तीर के साथ अलग होती है ठीक उसी तरह है हूँ होगा वापसी का प्रकार, लेकिन किसी भी तरह से मैं इसे याद कर रहा हूं और अब तक पुस्तकों/लेखों में स्पष्ट स्पष्टीकरण नहीं मिला है। हर बार जब मैं एक प्रकार के हस्ताक्षर देखता हूं तो मुझे इसे समझने में काफी समय लगता है। मुझे लगता है कि मैं उस पहेली के उस छोटे टुकड़े को याद कर रहा हूं जो "डिक्रिप्शन" स्पष्ट करता है।

    क्या कोई मुझे प्रबुद्ध कर सकता है?

  • उत्तर

    15

    लिखने के लिए होगा मुझे यकीन है कि वहाँ एक अर्थ कारण क्यों मानकों वास्तव में एक तीर के साथ अलग होती ही है कर रहा हूँ फ़ंक्शन रिटर्न प्रकार के रूप में, लेकिन किसी भी तरह से मैं खो रहा हूं और अब तक पुस्तकें/लेखों में स्पष्ट स्पष्टीकरण नहीं मिला है।

    आप पहले फ़ंक्शन को पढ़ रहे हैं सही है। तत्काल गूढ़ रहस्य के लिए, प्रकार हस्ताक्षर इस तरह व्यक्त कर रहे हैं:

    val functionName = inputType1 -> inputType2 -> ... -> inputTypeN -> returnType 
    

    आम तौर पर, तीर अंकन एक समारोह को इंगित करता है करी-सक्षम है।

    // val add4 : int -> int -> int -> int -> int 
    let add4 a b c d = a + b + c + d;; 
    
    // val f : (int -> int) 
    let f = add4 1 2 3 // returns (int -> int) waiting for last argument 
    

    क्योंकि समारोह curried है, तो आप तकनीकी रूप से इसे इस तरह लिख सकते हैं:

    val add4 : int -> (int -> (int -> (int -> int))) 
    

    मैं:

    // val add4 : int -> int -> int -> int -> int 
    let add4 = (fun a -> (fun b -> (fun c -> (fun d -> a + b + c + d))));; 
    
    // val f : (int -> int) 
    let f = fun x -> add4 1 2 3 x 
    

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

    +0

    साफ़ स्पष्टीकरण, धन्यवाद। इसे पढ़ने के बाद मुझे आश्चर्य है कि मैंने इसे पहले कैसे नहीं देखा ... –

    +0

    मुझे नहीं लगता कि यही कारण है कि हम तीर नोटेशन (प्रकारों में) का उपयोग करते हैं। आखिरकार, लैम्ब्डा कैलकुस में, हम टाइप सिंटैक्स में "->" का उपयोग करते हैं लेकिन "।" वाक्य वाक्यविन्यास में। [यह निश्चित रूप से, सच हो सकता है कि हम F> के संदर्भ में -> का उपयोग करते हैं क्योंकि हम -> प्रकारों और में उपयोग करते हैं। पहले से ही लिया गया था।] – petebu

    6

    हस्ताक्षर इस तरह से लिखे गए हैं क्योंकि Currying कहा जाता है। अपने कार्य का वर्णन करने का एक से थोड़ा अधिक सटीक तरीका है कि यह एक (समारोह है कि एक 'a लेता है और एक 'a करने के लिए एक 'b से एक फ़ंक्शन) लेता है और एक समारोह है कि एक 'a लेता है और एक 'a करने के लिए एक list<'b> से एक फ़ंक्शन देता है। इस वजह से टाइप हस्ताक्षर लिखा जा सकता है के रूप में

    ('a -> 'b -> 'a) -> ('a -> (list<'b> -> 'a)) 
    
    +0

    केवीबी के समान, अच्छा स्पष्टीकरण, धन्यवाद- दुर्भाग्य से मैं केवल एक ही जवाब स्वीकार कर सकता हूं –

    2

    कार्यात्मक प्रोग्रामिंग में हर कार्य वास्तव में केवल एक पैरामीटर है कि के लिए कारण।

    int -> int -> int 
    

    यह 2 पूर्णांक लेता है और एक पूर्णांक लौट:

    तो कहते हैं कि तुम एक समारोह योग के रूप में कहा जाता है की सुविधा देता है। अब यदि आप केवल एक int को पास करके इस फ़ंक्शन को कॉल करते हैं तो आपको कोई कंपाइलर त्रुटि नहीं मिलेगी, बल्कि वापसी मूल्य int int>> int का प्रकार होगा। तो आप देखते हैं कि यह तीर नोटेशन इस व्यवहार के साथ फिट बैठता है। इस व्यवहार को करी के रूप में जाना जाता है। चेक आउट: http://en.wikipedia.org/wiki/Currying

    +0

    अच्छा उदाहरण, उपरोक्त उत्तरों के लिए सही पूरक! लेकिन schönfinkeling इसके लिए एक बेहतर नाम है :-) –

    5

    आप एफ # में एक समान कार्य है जो एक प्रकार की तरह आप का प्रस्ताव कर रहे हैं है लिख सकता है (लेकिन एफ # में यह ('a * 'b -> 'a) * 'a * list<'b> -> 'a रूप में लिखा जाएगा हालांकि, मौजूदा समारोह का लाभ यह है कि यह आसान है। आंशिक रूप से केवल तर्कों का उपसर्ग प्रदान करके इसे लागू करें।उदाहरण के लिए:

    let sum = List.fold (+) 0 
    

    अपनी परिभाषा का उपयोग करके आप

    let sum l = List.fold((fun (x,y) -> x + y), 0, l) 
    
    +0

    भी बहुत अच्छा, बहुत बुरा आप केवल एक जवाब स्वीकार कर सकते हैं। –

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