2016-02-03 13 views
9

मैं पैरामीट्रिक प्रकार वाले मॉड्यूल के आधार पर फ़ंक्शन लिखने का तरीका जानने का प्रयास कर रहा हूं लेकिन मुझे कहीं भी कुछ भी नहीं मिल रहा है। मैंने जितनी ज्यादा हो सके समस्या को कम करने की कोशिश की और इस डमी उदाहरण के साथ समाप्त हो गया।पैरामैट्रिक स्थानीय रूप से अमूर्त प्रकार

module type Mappable = sig 
    type 'a t 
    val map : ('a -> 'b) -> 'a t -> 'b t 
end 

let plus (type m) (module M : Mappable with type 'a t = 'a m) (xs : int m) = 
    M.map (fun x -> x + 1) xs 

जो Error: Syntax error: module-expr expected त्रुटि उत्पन्न करता है।

यदि मैं 'a छोड़ देता हूं, तो मैं निम्न त्रुटि के साथ समाप्त होता हूं।

Error: In this `with' constraint, the new definition of t 
     does not match its original definition in the constrained signature: 
     Type declarations do not match: type t is not included in type 'a t 
     They have different arities. 

ऐसा करने के लिए सही वाक्यविन्यास क्या है?

उत्तर

7

मुझे विश्वास है कि आप यहां क्या करना चाहते हैं ओकैम 4.02.3 में असंभव है। चलो प्रकार चर के बिना एक सरलीकृत संस्करण देखें:

module type Mappable = sig 
    type t 
    val map : ('a -> 'b) -> t -> t 
end 

let plus (type m) (module M : Mappable with type t = m) (xs : m) = 
    M.map (fun x -> x + 1) xs 

ऊपर typable है और plus निम्न प्रकार है:

val plus : (module Mappable with type t = 'm) -> 'm -> 'm 

प्रकार m इसकी परिभाषा में एक चर 'm को निकाला गया है।

अब, अपने मूल कोड पर वापस जाएं और सोचें कि plus किस प्रकार का होना चाहिए। आप (type m) द्वारा सार m की कोशिश कर रहे बाद से, यह होना चाहिए:

val plus : (module Mappable with type 'a t = 'a 'm) -> 'a 'm -> 'a 'm 

दुर्भाग्य से, OCaml उच्च kinded बहुरूपता जो प्रकार 'a 'm के इस फार्म की अनुमति देता है का समर्थन नहीं करता। ऐसा लगता है कि प्रथम श्रेणी मॉड्यूल टाइपिंग सावधानी से कार्यान्वित नहीं की गई है।

आप निम्न शॉर्ट पेपर देख सकते हैं जो ओकैमल में उच्च दयालु बहुरूपता की वर्तमान (दुर्भाग्यपूर्ण) स्थिति बताता है। यह एक समाधान बताते हैं: कैसे स्पष्ट coersions की लागत से वर्तमान OCaml ढांचे में यह सांकेतिक शब्दों में बदलना करने के लिए:

https://ocamllabs.github.io/higher/lightweight-higher-kinded-polymorphism.pdf

मैं अपने आप को कभी नहीं की कोशिश की है, लेकिन एक ही तरीके को अपने उदाहरण के लिए लागू किया जा सकता है।

6

यह OCaml में संभव नहीं है के रूप में प्रकार बाधा एक नियमित रूप से मॉड्यूल प्रकार बाधा एक विशेष syntactic construct नहीं है, लेकिन, कि बहुरूपी प्रकार की अनुमति नहीं है:

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

एक सामान्य तरीके को एक मॉड्यूल ठोस प्रकार के लिए सभी प्रकार के चर बांधता है बनाने के लिए किया जाएगा:

module type Mapper = sig 
    type a 
    type b 
    type src 
    type dst 
    val map : (a -> b) -> src -> dst 
end 

let plus (type src) (type dst) 
    (module M : Mapper with type dst = dst 
         and type src = src 
         and type a = int 
         and type b = int) (xs : src) : dst = 
    M.map (fun x -> x + 1) xs 

अपने विशिष्ट उदाहरण में, वहाँ, 'a और 'b बाध्य करने के लिए कोई जरूरत नहीं है, क्योंकि वे कर रहे हैं अनिवार्य रूप से उपयोग नहीं किया, तो यह करने के लिए सरल किया जा सकता:

module type Mapper = sig 
    type src 
    type dst 
    val map : ('a -> 'b) -> src -> dst 
end 

let plus (type src) (type dst) 
    (module M : Mapper with type dst = dst 
         and type src = src) (xs : src) : dst = 
    M.map (fun x -> x + 1) xs 

बेशक, यह बहुत ही सीमित है, लेकिन इस दिन के लिए क्या संभव है। बजाय

2

functors आप कार्यों के लिए मॉड्यूल पास करना चाहते हैं, तो आप का उपयोग करना चाहिए:

module F (M : Mappable) = struct 
    let plus xs = M.map (fun x -> x + 1) xs 
end 
संबंधित मुद्दे