2013-03-25 5 views
5

Rust में रैखिक प्रकार एक रैखिक प्रकार प्रणाली है। ओकैमल में इसे अनुकरण करने के लिए कोई अच्छा (अच्छा) तरीका है? उदाहरण के लिए, ओकम्ल-लुआ का उपयोग करते समय, मैं यह सुनिश्चित करना चाहता हूं कि कुछ कार्य केवल तभी बुलाए जाते हैं जब लुआ एक विशिष्ट राज्य (ढेर के शीर्ष पर टेबल) में होता है।ओकैम

+0

आप मोनैडिक बाइंड में "रैखिक" प्रकार हैंडलिंग को छिपाने के लिए मोनैड का उपयोग कर सकते हैं और केवल मोनैडिक प्रकार को सार के रूप में निर्यात कर सकते हैं। –

+0

अनुकरण करके आपका क्या मतलब है? रनटाइम चेक? – didierc

+0

नहीं, स्थैतिक। "अनुकरण" के साथ मेरा मतलब है कि (करीब) रैखिक प्रकार प्रणाली प्राप्त करने के लिए मौजूदा प्रकार प्रणाली का उपयोग करना है। –

उत्तर

7

जॉन नदियों द्वारा सुझाए गए के रूप में, आप एक तरीका है कि प्रभाव एपीआई में रेखीय बाधा खाल में "effectful" गणना का प्रतिनिधित्व करने के लिए एक monadic शैली का उपयोग कर सकते हैं। नीचे एक उदाहरण है जहां ('a, 'st) t फ़ाइल हैंडल का उपयोग करके गणना का प्रतिनिधित्व करने के लिए उपयोग किया जाता है (जिसका पहचान यह गारंटी देने के लिए अंतर्निहित/अस्पष्ट है कि इसे डुप्लीकेट नहीं किया जा सकता है), उत्पाद 'a का परिणाम देगा और फ़ाइल हैंडल को छोड़ दें राज्य 'st (एक प्रेत प्रकार या तो "खुला" या "बंद" होता है)। आपको वास्तव में कुछ भी करने के लिए monad¹ के का उपयोग करना होगा, और इसका प्रकार सुनिश्चित करता है कि फ़ाइल हैंडल उपयोग के बाद सही ढंग से बंद हो जाते हैं।

module File : sig 
    type ('a, 'st) t 
    type open_st = Open 
    type close_st = Close 

    val bind : ('a, 's1) t -> ('a -> ('b, 's2) t) -> ('b, 's2) t 

    val open_ : string -> (unit, open_st) t 
    val read : (string, open_st) t 
    val close : (unit, close_st) t 

    val run : ('a, close_st) t -> 'a 
end = struct 
    type ('a, 'st) t = unit -> 'a 
    type open_st = Open 
    type close_st = Close 

    let run m = m() 

    let bind m f = fun() -> 
    let x = run m in 
    run (f x) 

    let close = fun() -> 
    print_endline "[lib] close" 

    let read = fun() -> 
    let result = "toto" in 
    print_endline ("[lib] read "^result); 
    result 

    let open_ path = fun() -> 
    print_endline ("[lib] open "^path) 
end  

let test = 
    let open File in 
    let (>>=) = bind in 
    run begin 
    open_ "/tmp/foo" >>= fun() -> 
    read >>= fun content -> 
    print_endline ("[user] read "^content); 
    close 
    end 
बेशक

, यह केवल आप एपीआई की शैली का स्वाद मिलता है के लिए है। अधिक गंभीर उपयोगों के लिए, ओलेग के monadic regions उदाहरण देखें।

तुम भी अनुसंधान प्रोग्रामिंग भाषा Mezzo, जो करना अलग संसाधनों के साथ एक रेखीय टाइपिंग अनुशासन के माध्यम से राज्य के महीन कुशल नियंत्रण (और संबंधित effectful पैटर्न) के साथ एमएल का एक प्रकार हो में रुचि हो सकती। ध्यान दें कि यह केवल अब के लिए एक शोध प्रयोग है, वास्तव में उपयोगकर्ताओं के लिए लक्षित नहीं है। ATS भी प्रासंगिक है, हालांकि अंत में कम एमएल-जैसे। जंग वास्तव में इन प्रयोगों के लिए उचित "व्यावहारिक" समकक्ष हो सकता है।

¹: यह वास्तव में एक इकाई नहीं है, क्योंकि यह कोई return/unit Combinator है, लेकिन बिंदु के रूप में monadic bind ऑपरेटर करता है प्रकार नियंत्रित अनुक्रमण के लिए मजबूर किया जा सके। हालांकि, map हो सकता है।

+0

क्या आप एक उपयोग उदाहरण भी प्रदान कर सकते हैं? मुझे अभी तक इस मोनैड चीज़ को वास्तव में नहीं मिला है। : पी –

+0

@ ओलेहेर्स्टेड: अंत में एक उपयोग उदाहरण है ('परीक्षण करें ...')। या आप कुछ और चाहते हैं? – gasche

+0

क्षमा करें, वह नहीं देखा! यह मेरे लिए जादू की तरह है, धन्यवाद! :) –