2016-09-10 6 views
5

में विस्तृत प्रकार ओस्कल में Control.Monad.Free के बाद ओकैम में एक मुफ्त मोनैड लाइब्रेरी लिखने की कोशिश कर रहा हूं, लेकिन मैं hoistFree के कार्यान्वयन में एक बिंदु पर अटक गया हूं।ओकेकल

hoistFree :: Functor g => (forall a. f a -> g a) -> Free f b -> Free g b 
hoistFree _ (Pure a) = Pure a 
hoistFree f (Free as) = Free (hoistFree f <$> f as) 

यहां अनुवाद में मेरा प्रयास है।

let rec hoistfree : 'b.('b t -> 'b t) -> 'a m -> 'a m = 
     fun f x -> match x with 
     | Return x -> Return x 
     | Free x -> Free (T.map (hoistfree f) (f x));; 

दुर्भाग्य से मुझे यह बताते हुए एक त्रुटि मिलती है कि मैं सही ढंग से जी के प्रकार को चौड़ा नहीं कर रहा हूं।

Error: This definition has type ('b m t -> 'b m t) -> 'b m -> 'b m 
     which is less general than 'a. ('a t -> 'a t) -> 'b m -> 'b m 

सब कुछ ठीक काम करता है अगर मैं समारोह प्रकार टिप्पणी सम्मिलित नहीं है, लेकिन उसके बाद त्रुटि संदेश दर्शाता है के रूप में, मैं च के लिए सामान्य प्रकार नहीं मिलता है। समस्या कहां है? मैं एफ के प्रकार को कैसे बढ़ा सकता हूं?

उत्तर

3

मैं OCaml साथ बहुत परिचित नहीं हूँ, लेकिन मेरा मानना ​​है कि के रूप में

let rec hoistfree : 'b. (('b t -> 'b t) -> 'a m -> 'a m) = 

बजाय

let rec hoistfree : ('b. ('b t -> 'b t)) -> 'a m -> 'a m = 

पूर्व एक बुनियादी बहुरूपी प्रकार है कि

let rec hoistfree : 'b.('b t -> 'b t) -> 'a m -> 'a m = 

पार्स किया गया है, उत्तरार्द्ध एक रैंक 2-प्रकार है जिसके लिए हिंडली-मिलनर की तुलना में प्रकार प्रणाली से अधिक समर्थन की आवश्यकता होती है।

आईआईआरसी, बाद में प्राप्त करने के लिए आपको कस्टम रैपर डेटा प्रकार को परिभाषित करने की आवश्यकता है। उदाहरण के लिए:

type poly = { polyf: 'a . 'a -> 'a } ;; 

let foo (x: poly): int = x.polyf 4;; 
let bar: poly = { polyf = fun x -> x } ;; 

let _ = print_string ("hello "^string_of_int (foo bar));; 
+0

उत्तर के लिए धन्यवाद। मैं अभी भी अपनी विशेष सेटिंग में अपना विचार लागू करने की कोशिश कर रहा हूं। – stackman