2012-08-05 37 views
9

नामित पैरामीटर के लिए ओकैम के तंत्र को समझने की कोशिश कर रहा है। मैं मूल बातें समझ है, लेकिन doc इस तरह एक उदाहरण दिखाता है:ओकैम के नामित पैरामीटर

# let f ~x ~y = x - y;; 
val f : x:int -> y:int -> int = <fun> 

# let x = 3 and y = 2 in f ~x ~y;; 
- : int = 1 

क्या वास्तव में जब केवल टिल्ड आवेदन में प्रयोग किया जाता है चल रहा है? क्या यह परिभाषाओं के समान ~x:x के लिए सिर्फ लघुरूप है? यदि हां, तो किसी को समझा सकता है क्यों यह:

# ListLabels.fold_left;; 
- : f:('a -> 'b -> 'a) -> init:'a -> 'b list -> 'a = <fun> 

# let add = (+) and i = 0 
in ListLabels.fold_left ~add ~i [1;2;3];; 

- : f:((add:(int -> int -> int) -> i:int -> 'a) -> 
    int -> add:(int -> int -> int) -> i:int -> 'a) -> 
init:(add:(int -> int -> int) -> i:int -> 'a) -> 'a = <fun> 

उत्तर

8

आदमी कहते हैं पैदा करता है "सावधान रहना है कि कार्यों ListLabels.fold_left जिसका परिणाम प्रकार एक प्रकार चर पूरी तरह से लागू किया रूप में माना जा कभी नहीं होगा है की तरह । "

यहां आपके उदाहरण में क्या होता है। सावधान रहें यह थोड़ा सा शामिल है। ListLabels.fold_left taks 3 तर्क, अर्थात् एक समारोह f लेबल, एक प्रारंभकर्ता init और एक सूची:

# ListLabels.fold_left;; 
- : f:('a -> 'b -> 'a) -> init:'a -> 'b list -> 'a = <fun> 

सिर्फ क्लासिक इस्तेमाल होता है।

अब,

let add = (+) and i = 0 
in ListLabels.fold_left ~add ~i [1;2;3];; 

आवेदन ListLabels.fold_left ~add ~i [1;2;3] में अधूरा माना जाता है (के रूप में आदमी कहते हैं)। इसका मतलब है कि `ListLabels.fold_left पहले इसके अनमोल तर्क, [1;2;3] प्राप्त करता है और f:('a -> int -> 'a) -> init:'a -> 'a प्रकार का फ़ंक्शन देता है। आइए इस फ़ंक्शन को कॉल करें।

आप दो नामित तर्क, add और i लेबल दे रहे हैं के बाद से, प्रकार 'a प्रकार add:'c -> ~i:'d -> 'e की एक कार्यात्मक प्रकार होना मान लिया जाता है।

चरadd और i के प्रकार के आधार पर, प्रकार 'cint -> int -> int होना चाहिए, और 'dint होना चाहिए।

'a प्रकार में उन मानों को प्रतिस्थापित करते हुए, हम प्राप्त करते हैं कि 'aadd:(int -> int -> int) -> i:int -> 'e है। और foo के प्रकार में इस जगह (मुझे खुशी है वहाँ कॉपी-पेस्ट ;-) अपने प्रकार

f:((add:(int -> int -> int) -> i:int -> 'e) 
    -> int 
    -> (add:(int -> int -> int) -> i:int -> 'e)) 
-> init:(add:(int -> int -> int) -> i:int -> 'e) 
-> (add:(int -> int -> int) -> i:int -> 'e) 

अनावश्यक कोष्ठकों निकाला जा रहा है, और अल्फा परिवर्तित है, (यानी नाम) 'e'a करने पर हम पाते हैं

f:((add:(int -> int -> int) -> i:int -> 'a) 
    -> int 
    -> add:(int -> int -> int) -> i:int -> 'a) 
-> init:(add:(int -> int -> int) -> i:int -> 'a) 
-> add:(int -> int -> int) -> i:int -> 'a 

यह foo का प्रकार है। लेकिन याद रखें कि आप foo को दो तर्क पारित कर रहे हैं, ~add और ~i लेबल किया गया है। तो अंत में आपको प्राप्त होने वाला मान add:(int -> int -> int) -> i:int -> 'a प्रकार नहीं है, लेकिन वास्तव में 'a टाइप करें। और आपका पूरा उदाहरण है, जैसा कि कंपाइलर द्वारा लौटाया गया है,

f:((add:(int -> int -> int) -> i:int -> 'a) 
    -> int 
    -> add:(int -> int -> int) -> i:int -> 'a) 
-> init:(add:(int -> int -> int) -> i:int -> 'a) 
-> 'a 
+0

वाह - क्या गड़बड़ है! यह वास्तव में समझ में आता है, बहुत बहुत धन्यवाद! – scry

+0

आपका स्वागत है, यह भी हल करना अच्छा था ;-) – jrouquie