2010-03-05 10 views
9

मैं ओकैमल नौसिखिया हूं। मैं "हैलो वर्ल्ड" टाइप स्निपेट के साथ खेल रहा हूं और इस स्थिति में आया हूं। यहाँ कुछ अतिरिक्त टिप्पणी के साथ दुभाषिया के साथ एक सत्र है:Printf.printf के साथ यह छोटा ओकैम स्निपेट क्यों नहीं काम करता है?

# let average a b = 
    (a +. b) /. 2.;; 
val average : float -> float -> float = <fun> 
# average 1. 4.;; 
- : float = 2.5 
# string_of_float (average 1. 4.);; 
- : string = "2.5" 

(* this fails...*) 
# let _ = Printf.printf (string_of_float (average 1. 4.));; 
Error: This expression has type string but an expression was expected of type 
     ('a, out_channel, unit) format = 
      ('a, out_channel, unit, unit, unit, unit) format6 

(* yet this works *) 
# "hello!";; 
- : string = "hello!" 
# let _ = Printf.printf "hello!";; 
hello!- : unit =() 

(* another failed attempt *) 
# let s = string_of_float (average 1. 4.);; 
val s : string = "2.5" 
# s;; 
- : string = "2.5" 
# let _ = Printf.printf s;; 
Error: This expression has type string but an expression was expected of type 
     ('a, out_channel, unit) format = 
      ('a, out_channel, unit, unit, unit, unit) format6 

(* and this also works?? *) 
# let _ = Printf.printf "2.5";; 
2.5- : unit =() 

तो यहाँ की स्थिति है। string_of_float (average 1. 4.) एक स्ट्रिंग देता है, जैसे "hello!" करता है। जब मैं "hello!"Printf.printf में देता हूं, तो यह अपेक्षित के रूप में काम करता है। जब मैं string_of_float (average 1. 4.) से Printf.printf देता हूं तो यह विफल रहता है और बताता है कि मुझे उम्मीद है कि स्ट्रिंग की उम्मीद नहीं है लेकिन वह अन्य अजीब प्रकार है। लेकिन "hello!" और "2.5" क्यों काम करते हैं?

क्या चल रहा है?

उत्तर

15

ओकैम में स्ट्रिंग अक्षर के अर्थ का एक "ओवरलोडिंग" है। संकलन समय पर, टाइप या चेकर सोचने के आधार पर, उन्हें या तो एक स्ट्रिंग के रूप में या एक प्रारूप के रूप में व्याख्या किया जा सकता है (जो टाइप सिस्टम में पूरी तरह से अलग चीजें हैं)। यदि यह निर्णय लेता है कि यह एक प्रारूप होना चाहिए, तो प्रारूप स्ट्रिंग को सीधे संकलन-समय पर पार्स किया गया है (यही कारण है कि यह संकलन समय पर printf को तर्क टाइप करने में सक्षम है)। (सी के विपरीत, जो रनटाइम पर स्ट्रिंग को पार करता है।) हालांकि, स्ट्रिंग से रनटाइम पर एक स्ट्रिंग में कनवर्ट करने का कोई आसान तरीका नहीं है। तो जब आप Printf.printf "2.5" देखते हैं, तो "2.5" वास्तव में एक स्ट्रिंग नहीं है, लेकिन एक विशेष प्रारूप प्रकार के रूप में जिसे संकलन-समय पर पार्स किया गया था। यही कारण है कि आप इसके लिए एक स्ट्रिंग को प्रतिस्थापित नहीं कर सकते हैं।

एक असंबंधित नोट पर, यदि आप केवल एक स्ट्रिंग मुद्रित करना चाहते हैं, तो आप print_string (या print_endline का उपयोग करना चाहेंगे यदि आप एक नई लाइन चाहते हैं)।

+0

यह मुझे समझ में आता है। धन्यवाद! – dimatura

+1

रन टाइम पर 'format6' बनाने में सक्षम नहीं है वास्तव में ... कमी है। क्या एक ही लक्ष्य प्राप्त करने के लिए कोई रास्ता है (इसे स्वयं लिखने से छोटा)? (उदाहरण के लिए, आप रनटाइम पर निर्धारित स्पेस की मनमानी संख्या से स्ट्रिंग कैसे पैड करते हैं? सी में हम 'sprintf (sprintf ("%%% डीएस", चौड़ाई), str) ' – kizzx2

+0

@ kizzx2: इस विशेष कार्य के लिए , एक वैकल्पिक समाधान है: प्रारूप स्ट्रिंग सिंटैक्स चौड़ाई या परिशुद्धता को तारांकन द्वारा प्रतिस्थापित करने की अनुमति देता है, इस मामले में यह इसे एक अतिरिक्त तर्क से ले जाएगा जो मुख्य तर्क से पहले है: 'Printf.sprintf"% * s "चौड़ाई str'; यह वाक्यविन्यास सी 99, पर्ल, पायथन, रूबी, गो, आदि में भी उपलब्ध है लेकिन निश्चित रूप से यह केवल एक विशेष मामला है; अन्य चीजों के लिए आप भाग्य से बाहर हो सकते हैं। एक ऑपरेटर '^^' है OCaml प्रारूपों को एक साथ जोड़ने के लिए, लेकिन आपको अभी भी पहले स्थान पर जोड़ने के लिए प्रारूपों की आवश्यकता है, इसलिए मुझे नहीं पता कि यह कितना उपयोगी है। – newacct

3
Printf.printf "%s" anyStringExpr 

काम करेगा। Printf के लिए पहला तर्क कुछ हद तक जादुई है। (अन्य विवरण भरेंगे।)

+0

हाँ, पहला तर्क एक प्रारूप स्ट्रिंग है जिसमें निर्देश होते हैं, और जब लागू होता है तो पैरामीटर के रूप में निर्देशों की संख्या के साथ एक फ़ंक्शन देता है। निश्चित रूप से जादुई। – nlucaroni

+1

की तरह। वैसे भी यह पूरी तरह से टाइप की गई प्रिंटफ सुविधा के साथ वास्तव में बहुत अच्छा है। – bltxd

+0

एचएम ... इससे अधिक प्रश्न उठते हैं। एक कार्यात्मक परिप्रेक्ष्य से मैं उम्मीद करता हूं कि अगर एफ (एक्स) = वाई, जी (एफ (एक्स)) = जी (वाई)। यह printf के साथ क्यों काम नहीं करता है? क्या इस तथ्य के साथ इसका कोई संबंध नहीं है कि प्रिंटफ को मूल रूप से दुष्प्रभाव होना चाहिए? क्या इस तरह का 'जादू' आम है? – dimatura

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