ऐसे कई मामले हैं जहां आप उन दो मॉड्यूल को संगत होना चाहते हैं। एक सरल उपयोग के मामले निम्नलिखित है:
module Hashtbl = struct ... (* definition in the stdlib *) end
module ExtHashtbl = struct ... (* my own layer on top of it *) end
मैं ExtHashtbl.t
Hashtbl.t
के साथ संगत होना चाहते हैं, इसलिए है कि मैं कर सकते हैं कोड के बीच में ExtHashtbl
के कार्यों Hashtbl.t
का उपयोग कर, या मान जो किसी के द्वारा बनाया गया है पर संचालित करने के लिए अन्यथा केवल Hashtbl
लाइब्रेरी के बारे में पता है, न कि मेरी खुद की सामग्री।
एमएल के सिद्धांत में मॉड्यूल एक ऑपरेशन के साथ जितना संभव हो उतना समीकरणों एक मॉड्यूल परिभाषा समृद्ध, उन्हें हस्ताक्षर में उजागर "मजबूत बनाने" कहा जाता है। विचार यह है कि यदि आप अधिक अमूर्तता (कम समीकरण) चाहते हैं, तो आप हमेशा इसे प्रतिबंधित करने के लिए एक प्रकार के हस्ताक्षर का उपयोग कर सकते हैं, इसलिए यह समीकरणों के लिए सख्ती से अधिक सामान्य है।
स्थिति मज़दूरों के मामले में थोड़ा अलग है। कि बजाय सरल मॉड्यूल के रूप ए और बी को परिभाषित करने के विचार करें, तो आप उन्हें खाली हस्ताक्षर पर functors बनाया था:
module A (U : sig end) = struct include M end
module B (U : sig end) = struct include M end
वहाँ तो, जो कि कहा जाता है "उत्पादक हैं एमएल मॉड्यूल प्रणालियों में functors के दो अलग विचार "(functor से प्रत्येक मंगलाचरण उत्पन्न करता है" फ्रेश "है कि अन्य आमंत्रण के साथ असंगत हैं प्रकार के), और लोगों को बुलाया" अनुप्रयोगी "(सभी बराबर तर्क पर functor के आमंत्रण संगत प्रकार)। OCaml प्रणाली एक अनुप्रयोगी तरह से बर्ताव करता है अगर आप इसे एक मॉड्यूल तर्क यह है कि (अधिक आम तौर पर एक पथ) नाम दिया गया है के साथ का दृष्टांत, और एक उत्पादक तरह से अगर आप इसे एक मॉड्यूल तर्क यह है कि अज्ञात है के साथ का दृष्टांत में।
आप जेवियर लेरोय के 2000 पेपर A Modular Module System (PDF) (वेबपृष्ठ A few papers on Caml से) में ओकैम मॉड्यूल सिस्टम के बारे में जानना चाहते हैं उससे कहीं ज्यादा सीख सकते हैं। ऊपर वर्णित सभी स्थितियों के लिए आपको नीचे दिए गए कोड उदाहरण भी मिलेंगे।
एमएल मॉड्यूल सिस्टम, विशेष रूप से Anreas Rossberg, डेरेक ड्रेयर और क्लाउडियो रूसो द्वारा पर हाल के काम, "अनुप्रयोगी" और "उत्पादक" functors के बीच क्लासिक भेद करने के लिए एक अलग दृष्टिकोण लाने के लिए एक प्रवृत्ति है। वे दावा करते हैं कि उन्हें "शुद्ध" और "अशुद्ध" मज़दूरों के अनुरूप होना चाहिए: मकसद जिनके आवेदन साइड इफेक्ट्स करते हैं, हमेशा जेनरेटिव होते हैं, जबकि मज़ेदार जो केवल शुद्ध शर्तों को लाते हैं उन्हें डिफ़ॉल्ट रूप से आवेदक होना चाहिए (इस तरह असंतुलन को मजबूर करने के लिए कुछ सीलिंग निर्माण के साथ, इस प्रकार अमूर्त प्रदान करना)।
module type S = sig
type t
val x : t
end;;
module M : S = struct
type t = int
let x = 1
end;;
(* definitions below are compatible, the test type-checks *)
module A1 = M;;
module B1 = M;;
let _ = (A1.x = B1.x);;
(* definitions below are each independently sealed with an abstract
signature, so incompatible; the test doesn't type-check *)
module A2 : S = M;;
module B2 : S = M;;
let _ = (A2.x = B2.x);;
(*This expression has type B2.t but an expression was expected of type A2.t*)
(* note: if you don't seal Make with the S module type, all functor
applications will be transparently equal to M, and all examples below
then have compatible types. *)
module Make (U : sig end) : S = M;;
(* same functor applied to same argument:
compatible (applicative behavior) *)
module U = struct end;;
module A3 = Make(U);;
module B3 = Make(U);;
let _ = (A3.x = B3.x);;
(* same functor applied to different argument:
incompatible (applicative behavior) *)
module V = struct end;;
module A4 = Make(U);;
module B4 = Make(V);;
let _ = (A4.x = B4.x);;
(* This expression has type B4.t = Make(V).t
but an expression was expected of type A4.t = Make(U).t *)
(* same functor applied to non-path (~unnamed) arguments:
incompatible (generative behavior) *)
module A5 = Make(struct end);;
module B5 = Make(struct end);;
let _ = (A5.x = B5.x);;
(* This expression has type B5.t but an expression was expected
of type A5.t *)
धन्यवाद, लेकिन मेरा प्रश्न दार्शनिक प्रकृति से अधिक था। हो सकता है कि संकलक का अनुमान लगाएं कि यह वही प्रकार क्यों है क्योंकि यह कर सकता है, और संकलक हमेशा सबसे सामान्य प्रकार चाहता है। –