2011-09-04 23 views
15

मैंने अतीत में एसएमएल में थोड़ा सा काम किया है, लेकिन अब मैं और अधिक दिलचस्प भागों में जाना शुरू कर रहा हूं।एसएमएल: संरचना के कार्यान्वयन को छिपाने के लिए abstype का उपयोग करने और हस्ताक्षर का उपयोग करने के बीच क्या अंतर है?

abstype...with...end निर्माण का उपयोग करके, मैं चीजें बना सकता हूं लेकिन उनके कार्यान्वयन के विवरण छुपा रहता हूं। मैं उस चीज़ का हस्ताक्षर भी बना सकता हूं जिसे मैं बनाना चाहता हूं, और उस हस्ताक्षर का पालन करने वाली संरचना बनाने के लिए :> ऑपरेटर का उपयोग करें जो कार्यान्वयन विवरण छुपा रहता है।

हस्ताक्षर/संरचनाएं abstypes का एक और सामान्य संस्करण नहीं हैं? मैं abstypes के साथ क्या कर सकता हूँ कि मैं हस्ताक्षर/संरचनाओं के साथ नहीं कर सकता? मैं कभी भी abstype का उपयोग क्यों करना चाहूंगा?

मदद के लिए अग्रिम धन्यवाद!

एक उदाहरण के रूप:

signature SET = sig 
    type set 
    val empty: set 
    val insert: int * set -> set 
    val member: int * set -> bool 
end 

structure Set :> SET = struct 
    type set = int list 
    val empty = [] 
    fun insert(x, s) = x::s 
    fun member(x, []) = false 
     | member(x, h::t) = (x = h) orelse member(x, t) 
end 

लगता है कम से कम के रूप में शक्तिशाली रूप में

abstype AbsSet = absset of int list with 
    val empty = absset([]) 
    fun insert(x, absset(s)) = absset(x::s) 
    fun member(x, absset([])) = false 
     | member(x, absset(h::t)) = (x = h) orelse member(x, absset(t)) 
end 

उत्तर

8

क्यों मैंने कभी abstype का उपयोग करना चाहते हैं?

सबसे आसान से शुरू, आप नहीं करेंगे। कम से कम मैं एक अच्छे कारण से नहीं आ सकता।


नहीं कर रहे हैं हस्ताक्षर/संरचनाओं सिर्फ abstypes की एक अधिक सामान्य संस्करण?

अच्छा, मुझे लगता है कि हमें एसएमएल के इतिहास पर एक नज़र रखना है। अपारदर्शी (...:> ...) हस्ताक्षर मिलान एसएमएल '90 के हिस्से के रूप मॉड्यूल 1.3.9. opaque signature matching :>

के बारे में इस smlnj दस्तावेज़ ... जिसका उद्देश्य के एक "सार" उदाहरण बनाने के लिए था पर समझाया नहीं था हस्ताक्षर एसआईजी। यह सुविधा विभिन्न कारणों से एसएमएल '90 से बाहर थी, लेकिन इसकी आवश्यकता असली थी।

मैं इसे शामिल नहीं के लिए तर्क के बारे में पता नहीं है, लेकिन जहाँ तक मुझे पता है मैक्वीन abstype जो एसएमएल '90 का हिस्सा था की थी "आगे" और किसी कारण से एसएमएल में निकाला नहीं गया था '97 (शायद पीछे की संगतता?)

हालांकि उनके बीच मूल रूप से अंतर है, abstype कोर भाषा का हिस्सा है जहां मॉड्यूल/हस्ताक्षर/फ़ैक्टर मॉड्यूल सिस्टम का हिस्सा हैं।


मैं abstypes कि मैं हस्ताक्षर/संरचनाओं के साथ ऐसा नहीं कर सकते के साथ क्या कर सकते हैं?

मैं कुछ भी नहीं कर सकता। हालांकि मुझे पूरा यकीन है कि कुछ उदाहरण बनाना आसान होगा कि आप अपारदर्शी हस्ताक्षर मिलान का उपयोग कर सकते हैं और abstypes के साथ नहीं कर सकते हैं।


अद्यतन

उत्तराधिकारी मिलीलीटर विकी है

पेज Degrade abstype to derived form वास्तव में एक छोटे से अनौपचारिक विवरण के बारे में abstype एक बचे हुए किया जा रहा होता है।

कई अन्य लोगों के साथ, वे Defects in the Revised Definition of Standard ML पेपर के अनुभागों को भी संदर्भित करते हैं जिनमें abstype की परिभाषा में कुछ "मामूली" त्रुटियों/दोषों के बारे में विवरण शामिल हैं, हालांकि उनका लिंक मर रहा है। "मानक एमएल की संशोधित परिभाषा" एसएमएल '97 की परिभाषा है।

+0

लिंक अब तय किया गया है। :) –

+1

एकमात्र चीज जो आप abstype के साथ कर सकते हैं कि आप मॉड्यूल के साथ नहीं कर सकते (कम से कम सादे SML'97 में) स्थानीय रूप से '' let'' के अंदर एक अमूर्त प्रकार को परिभाषित कर रहा है। लेकिन ऐसा कुछ नहीं है जिसे किसी ने कभी जलन की जरूरत महसूस की है ... –

3

एक बड़ा कारण है कि abstype यथार्थवादी अनुप्रयोगों के लिए अभी भी आवश्यक है, बहुत प्रिंटिंग को अपनाना है। यह एसएमएल/एनजे और पॉली/एमएल के चौराहे को संदर्भित करता है - मुझे नहीं पता कि इस संबंध में मल्टन कैसे काम करता है (इसमें उचित अपूर्ण नहीं है)।

कार्य सरल है: एक अमूर्त डेटाटाइप परिभाषित करें (जो समानता को रिसाव नहीं करता है) और इसके लिए एक शानदार सुंदर प्रिंटर प्रदान करता है। - संकलक विशिष्ट लाइनों की जरूरत है

structure A1: 
sig 
    type t val a: t val b: t -> t val print: t -> string 
end = 
struct 

abstype t = A of int 
with 
    val a = A 42 
    fun b (A i) = A (i + 1) 
    fun print (A i) = "{"^Int.toString i^"}[1]" 
end 

end; 

(* works for Poly/ML 5.3, 5.4, 5.5: 
PolyML.addPrettyPrinter (fn depth => fn pretty => fn x => PolyML.PrettyString (A1.print x)); 
*) 

(* works for SML/NJ 110.xx: 
CompilerPPTable.install_pp ["A1", "t"] (fn pps => fn x => PrettyPrint.string pps (A1.print x)); 
*) 

A1.a इस हास्यास्पद उदाहरण में {42}[1] प्रिंट चाहिए: केवल (अर्ध पोर्टेबल) जवाब यह है कि मैं जानता हूँ कि SML'90 शैली गैर अपारदर्शी हस्ताक्षर मिलान के साथ सादे पुराने abstype का उपयोग करता है अन-टिप्पणी करने के लिए। यह निश्चित रूप से एसएमएल'97 मानक के बाहर है, या बाद में एमएल -2000 और उसके बाद के प्रयासों के बाहर है, लेकिन यह एसएमएल/एनजे और पॉली/एमएल दोनों के लिए काम करता है, क्योंकि वे आज भी उपलब्ध हैं। कुछ अर्थों में आप कुछ पुरानी एसएमएल'90 और प्री-एसएमएल संस्कृति को चमकते हुए देखते हैं, यहां तक ​​कि कुछ भी एलआईएसपी हैकिंग को कम करने के लिए। (संरचना परिभाषा के लिए उपर्युक्त पोस्ट-ल्यूड्स को मजाकिया रैपर में बदल दिया जा सकता है जो एसएमएल को संकलित समय पर संकलित करने के तरीके को अपनाने के लिए प्रेरित करता है, जिससे स्रोत दोनों पोर्टेबल दिखाई देते हैं।)

ध्यान दें कि इसाबेल जैसे अनुप्रयोगों के लिए , एचओएल 4, प्रूफपावर, एमएल सुंदर प्रिंटिंग को अपरिवर्तनीय अनिवार्य है, जो भी एसएमएल मानक लेखक कह सकते हैं।

structure A2 :> 
sig 
    type t val a: t val b: t -> t val print: t -> string 
end = 
struct 

datatype t = A of int 

val a = A 42 
fun b (A i) = A (i + 1) 
fun print (A i) = "{"^Int.toString i^"}[2]" 

(* works, but non-portable: 
val _ = 
    PolyML.addPrettyPrinter (fn depth => fn pretty => fn x => PolyML.PrettyString (print x)) 
*) 

(* does not work (scope problem -- no pp): 
val _ = 
    CompilerPPTable.install_pp ["A2", "t"] (fn pps => fn x => PrettyPrint.string pps (A2.print x)); 
*) 

end; 

(* does not work (no pp): 
    PolyML.addPrettyPrinter (fn depth => fn pretty => fn x => PolyML.PrettyString (A2.print x)); 
*) 

(* does not work (no pp): 
CompilerPPTable.install_pp ["A2", "t"] (fn pps => fn x => PrettyPrint.string pps (A2.print x)); 
*) 


structure A3 :> 
sig 
    type t val a: t val b: t -> t val print: t -> string 
end = 
struct 

type t = int 

val a = 42 
fun b i = i + 1 
fun print i = "{"^Int.toString i^"}[3]" 

(* does not work (overrides pp for int): 
val _ = 
    PolyML.addPrettyPrinter (fn depth => fn pretty => fn x => PolyML.PrettyString (print x)) 
*) 

(* does not work (scope problem -- no pp) 
val _ = CompilerPPTable.install_pp ["A2", "t"] (fn pps => fn x => PrettyPrint.string pps (A2.print x)); 
*) 

end; 

(* works: 
    PolyML.addPrettyPrinter (fn depth => fn pretty => fn x => PolyML.PrettyString (A3.print x)); 
*) 

(* does not work (no pp): 
CompilerPPTable.install_pp ["A3", "t"] (fn pps => fn x => PrettyPrint.string pps (A3.print x)); 
*) 

मुझे आशा है कि मैं सभी विषम मामलों सही मिल गया है:

यहाँ दो अधिक संस्करणों कि SML'97 और अपारदर्शी हस्ताक्षर :> मिलान के साथ लाइन में अधिक हैं, लेकिन समान रूप से काम करने के लिए असफल हो रहे हैं। विभिन्न एसएमएल के लिए "नो पीपी" सीटेशन अलग नहीं है: पॉली/एमएल मूल प्रतिनिधित्व प्रिंट करता है, जबकि एसएमएल/एनजे कुछ भी प्रिंट नहीं करता है (बस प्लेसहोल्डर के रूप में डैश)। "Untagged" अपारदर्शी प्रकार विशेष रूप से बुरा है: पॉली/एमएल में यह int के लिए सुंदर प्रिंटर ओवरराइड करेगा, लेकिन एसएमएल/एनजे के लिए यह कुछ भी नहीं करता है, जो भी बुरा है।

+0

वाह, यह पहली बार मैंने कभी सुना है। निश्चित नहीं है कि मैं विशिष्ट कार्यान्वयन की गैर-पोर्टेबल हैकी सुविधाओं के साथ अपने आकस्मिक इंटरप्ले द्वारा अप्रचलित पुराने निर्माण को प्रेरित करने के बारे में कैसा महसूस करूंगा। :) –

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

  • कोई संबंधित समस्या नहीं^_^