2016-12-14 9 views
5

docs for the Pervasives.compare function राज्य कि-1, 0 और 1 से कुछ और लौटने की तुलना कर सकते हैं?

compare x y रिटर्न 0 अगर xy के बराबर है, एक नकारात्मक पूर्णांक अगर xy से कम है, और उसे धन पूर्णांक अगर xy से अधिक है।

यह पता चलता है यह लौट सकते हैं किसी भी नकारात्मक या सकारात्मक पूर्णांक, बस -1 नहीं या 1, greater- या कम सत्ता प्रतिनिधित्व करते हैं। हालांकि, क्या यह वास्तव में होता है?

इस तरह

match String.compare key new_key with 
    | 1 -> Node (left,    insert new_key right, key) 
    | -1 -> Node (insert new_key left, right,    key) 
    | _ -> Node (left,    right,    key) 

और अधिक कठिन लेखन कोड बनाना होगा (when का उपयोग कर, शायद?)।

मुझे विशेष रूप से String.compare में रूचि है। its implementation पर एक नज़र डालने के बाद, यह केवल Pervasives.compare पर आगे बढ़ता है, जो बदले में external का उपयोग करके लागू किया जाता है। कोई विचार नहीं कि यह क्या करता है।

+1

मैंने अभी ओकैमल सीखना शुरू कर दिया है। यह टैग आपको इस टैग पर पोस्ट करने के लिए वास्तव में अच्छा है^_^ – naomik

उत्तर

3

मुझे आश्चर्य है कि क्यों किसी को सीधे प्रस्तावित रैपर @ काने का उपयोग नहीं करना चाहिए। आपका कोड बन जाएगा:

match String.compare key new_key with 
    | 0    -> Node (left, right, key) 
    | x when x > 0 -> Node (left, insert new_key right, key) 
    | _ (* x < 0*) -> Node (insert new_key left, right, key) 

जो फ़ंक्शन कॉल सहेजता है और -1/0/1 दृष्टिकोण से काफी लंबा नहीं है। इसके अलावा, उपयोगकर्ता द्वारा अक्सर तुलना की जाती है (उदाहरण के लिए Set.OrderedType देखें), जहां बाधा का उल्लंघन किया जा सकता है।

+0

हां, यह मेरी पसंद का समाधान होगा, लेकिन मुझे आश्चर्य हुआ कि यह मूर्खतापूर्ण है या नहीं? क्या यह निर्माण उद्यम ओकंपल परियोजनाओं में उपयोग किया जाता है? – Bergi

+0

मैं प्रोग्रामिंग एंटरप्राइज़ स्तर ओकंपल नहीं कर रहा हूं, लेकिन जब काफी आम है तो पैटर्न मिलान। –

3

क्या यह वास्तव में होता है?

सं

Pervasives.compare देशी रूप external का उपयोग कर कार्यान्वित किया जाता है।

मैं तो ऐसा लगता है यह वास्तव में compare "a" "abc" (-2) की तरह तार के लिए एक मनमाना पूर्णांक लौट सकते हैं इस compare.c को संदर्भित करता है, जो

#define LESS -1 
#define EQUAL 0 
#define GREATER 1 

mlsize_t len1 = caml_string_length(v1); 
mlsize_t len2 = caml_string_length(v2); 
int res = memcmp(String_val(v1), String_val(v2), len1 <= len2 ? len1 : len2); 
if (res < 0) return LESS; 
if (res > 0) return GREATER; 
if (len1 != len2) return len1 - len2; 

का उपयोग कर string case को लागू करता है लगता है।

लेकिन अगर हम ओकैम में कोशिश करते हैं, तो ऐसा नहीं होता है और केवल -1 देता है। क्यों नहीं?
क्योंकि real compare function कि OCaml कोड के संपर्क में है परिणामों को सामान्यीकृत करता है:

CAMLprim value caml_compare(value v1, value v2) 
{ 
    intnat res = compare_val(v1, v2, 1); 
    if (res < 0) 
    return Val_int(LESS); 
    else if (res > 0) 
    return Val_int(GREATER); 
    else 
    return Val_int(EQUAL); 
} 

तो यह वास्तव में किसी भी int अन्य उन तीन से वापस नहीं लौट सकते।

6

अपने आप से एक जवाब से पता चलता है कि वर्तमान कार्यान्वयन में कोई अन्य मान वापस नहीं किया जा सकता है। हालांकि, मैं उस पर भरोसा करने के लिए बहुत सावधान रहूंगा। जब तक compareदस्तावेज को तीन मूल्यवान होने के कारण, ओकैमल के भविष्य के संस्करण उस व्यवहार को बदल सकते हैं।

[संपादित करें, एक टिप्पणी का जवाब दे] आदेश में अनाड़ी मामले भेद से बचने के लिए (आपके मूल प्रश्न में संकेत दिया), तो आप एक समारोह में compare लपेट कर सकते हैं कि रिटर्न एक तीन मूल्यों इसलिए की तरह टाइप करें:

type comparison = Less | Equal | More 

let my_compare a b = match compare a b with 
| 0 -> Equal 
| c when c>0 -> More 
| _ -> Less 
+0

हाँ, मैं पूरी तरह से सहमत हूं। तो Ocaml में एक बेवकूफ तीन-तरफा तुलना कैसे दिखाई देगी? – Bergi

+0

मानक पुस्तकालय में ऐसा 'तुलना' प्रकार क्यों नहीं है? – Bergi

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