2009-12-31 8 views
23

में functors निम्नलिखित बहुरूपी कार्योंउच्च आदेश प्रकार निर्माणकर्ता और OCaml

let id x = x;; 
let compose f g x = f (g x);; 
let rec fix f = f (fix f);;  (*laziness aside*) 

प्रकार/प्रकार कंस्ट्रक्टर्स या मॉड्यूल/functors के लिए लिखा जा सकता है? मैंने

type 'x id = Id of 'x;; 
type 'f 'g 'x compose = Compose of ('f ('g 'x));; 
type 'f fix = Fix of ('f (Fix 'f));; 

प्रकारों के लिए प्रयास किया लेकिन यह काम नहीं करता है।

data Id x = Id x 
data Compose f g x = Compose (f (g x)) 
data Fix f = Fix (f (Fix f)) 

-- examples: 
l = Compose [Just 'a'] :: Compose [] Maybe Char 

type Natural = Fix Maybe -- natural numbers are fixpoint of Maybe 
n = Fix (Just (Fix (Just (Fix Nothing)))) :: Natural -- n is 2 

-- up to isomorphism composition of identity and f is f: 
iso :: Compose Id f x -> f x 
iso (Compose (Id a)) = a 
+1

मैं "100% निश्चित नहीं हूँ, क्योंकि मैं हास्केल पता नहीं है और मैं क्या FGX = ... लिखें वास्तव में हास्केल में इसका मतलब है पर स्पष्ट नहीं हूँ, लेकिन आप को पता है कि रुचि हो सकती है ओसीएएमएल के विकास संस्करण में प्रथम श्रेणी के मॉड्यूल हैं। – nlucaroni

+1

मुझे यकीन है कि आप इसे एमएल में नहीं कर सकते हैं, क्योंकि आपको उच्च-प्रकार के पॉलीमोर्फिज्म की आवश्यकता है। क्या आप कुछ उदाहरण दे सकते हैं कि आप इन प्रकारों का उपयोग हास्केल में कैसे करेंगे? –

+0

nlucaroni, बहुत रोचक! (लिंक http://caml.inria.fr/cgi-bin/viewcvs.cgi/ocaml/branches/fstclassmod/ मेरा मानना ​​है) क्रिस कॉन्वे, मैंने कुछ उदाहरण जोड़े। – sdcvvc

उत्तर

29

हास्केल उच्च तरह का चर टाइप अनुमति देता है:

यहाँ प्रकारों के लिए एक हास्केल संस्करण है। कैमल समेत एमएल बोलियां, केवल "*" प्रकार के प्रकार चर की अनुमति देती हैं। , सादे अंग्रेजी में अनुवाद किया

  • हास्केल में, एक प्रकार चर gMaybe या IO या सूचियों की तरह एक "प्रकार निर्माता" के अनुरूप कर सकते हैं। तो आपके हास्केल उदाहरण में g x ठीक होगा (शब्दकोष: "अच्छी तरह से दयालु") उदाहरण के लिए gMaybe और xInteger है।

  • एमएल में, एक प्रकार चर 'goption या list की तरह एक प्रकार निर्माता के लिए कभी नहीं, int या string की तरह एक "जमीन प्रकार" के लिए एक ही अनुरूप कर सकते हैं। इसलिए कभी किसी अन्य प्रकार के प्रकार को लागू करने का प्रयास करने के लिए सही नहीं है।

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

आईएनआरआईए के लोगों ने एमएल में कई अन्य बदलाव किए हैं, और मुझे आश्चर्य है कि उन्होंने इसे कभी नहीं बनाया है। जब मैं एमएल में प्रोग्रामिंग कर रहा हूं, तो मुझे उच्च-प्रकार के प्रकार चर होने का आनंद हो सकता है। लेकिन वे वहां नहीं हैं, और functors का उपयोग करके आप जिन उदाहरणों के बारे में बात कर रहे हैं, उन्हें एन्कोड करने का कोई तरीका नहीं है।

+0

ठीक है, ओकम्ल को पहली बार रिलीज़ किया गया था 1 99 6 में, उस समय लेट-पॉलिमॉर्फिज्म प्रतिबंध पूर्ण प्रकार की अनुमान और प्रिंसिपल टाई सुनिश्चित करने का एक आसान तरीका था पिंग। मुझे नहीं पता कि 'काफी आसान' के लिए आपका संदर्भ क्या है, लेकिन रैंक -2 पॉलिमॉर्फिज्म के लिए पुनर्निर्माण टाइप केवल [1999] (http://dx.doi.org/10.1145/292540.292556) में पाया गया था। और निश्चित रूप से यह रैंक -3 और उच्च (ibid) के लिए अपरिहार्य है। – huitseeker

+3

@huitseeker: प्रश्न रैंक-2 प्रकारों के बारे में नहीं है (जहां आप हास्केल में 'फॉरल' क्वांटिफायर घोंसला करते हैं, लेकिन उच्च-आदेश प्रकारों के बारे में (जहां आप घोंसला '-> ') हैं। – sdcvvc

+0

"गहरा कारण" समझाया गया है [यहां] (https://news.ycombinator.com/item?id=12331905), [यहां] (http://lambda-the-ultimate.org/node/5391), और धारा _1.1 में उपनाम समस्या_ [पेज 2] पर (https://www.cl.cam.ac.uk/~jdy22/papers/lightweight-higher-kinded-polymorphism.pdf#page=2) _Lightweight के उच्च-दयालु पॉलीमोर्फिज्म_। स्कैला के डीओटी में एचकेटी के परिष्करण (अमूर्त प्रकार) मॉडल, [प्रदर्शन] [http://archive.is/KbljQ#selection-8135.21-8147.41) अनुमान समस्या। सार निर्भर प्रकार [हस्ताक्षर के प्रकार के लिए encapsulate] (http://lambda-the-ultimate.org/node/5121#comment-84669)। –

17

आप उच्च क्रम प्रकारों के स्थान पर प्रकार के स्थान पर मॉड्यूल का उपयोग करके, और मल्टीक्टरों (उच्च-आदेश मॉड्यूल) का उपयोग करके ओकैमल में कुछ ऐसा कर सकते हैं। लेकिन यह बहुत अधिक दिखता है और इसमें टाइप-इनफरेंस क्षमता नहीं है, इसलिए आपको मैन्युअल रूप से बहुत सारी चीज़ें निर्दिष्ट करनी होंगी।

module type Type = sig 
    type t 
end 

module Char = struct 
    type t = char 
end 

module List (X:Type) = struct 
    type t = X.t list 
end 

module Maybe (X:Type) = struct 
    type t = X.t option 
end 

(* In the following, I decided to omit the redundant 
    single constructors "Id of ...", "Compose of ...", since 
    they don't help in OCaml since we can't use inference *) 

module Id (X:Type) = X 

module Compose 
    (F:functor(Z:Type)->Type) 
    (G:functor(Y:Type)->Type) 
    (X:Type) = F(G(X)) 

let l : Compose(List)(Maybe)(Char).t = [Some 'a'] 

module Example2 (F:functor(Y:Type)->Type) (X:Type) = struct 
    (* unlike types, "free" module variables are not allowed, 
    so we have to put it inside another functor in order 
    to scope F and X *) 
    let iso (a:Compose(Id)(F)(X).t) : F(X).t = a 
end 
+0

कृपया, प्रश्न के फिक्स प्रकार कन्स्ट्रक्टर से संबंधित एक मॉड्यूल जोड़ें। – Romildo

0

अच्छा ... मैं उच्च-आदेश-प्रकारों और नस्केल प्रोग्रामिंग का विशेषज्ञ नहीं हूं। लेकिन यह एफ # (जो OCaml है) के लिए ठीक हो रहा है, तो आप इन के साथ काम कर सकता था:

type 'x id = Id of 'x;; 
type 'f fix = Fix of ('f fix -> 'f);; 
type ('f,'g,'x) compose = Compose of ('f ->'g -> 'x);; 

पिछले एक मैं के रूप में मैं कुछ भी बेहतर के साथ नहीं आया था टपल को लपेटा ...

+0

हालांकि, मेरा मतलब था '(सूची, विकल्प, int) compose' जैसा कि' (int विकल्प) सूची' के बराबर होगा। – sdcvvc

+0

मुझे लगता है कि यह विकल्प प्रकारों का उपयोग करके किया जा सकता है। एफ # में आप .NET-way में भी कई प्रकार के पैराम का उपयोग कर सकते हैं: लिखें <'f, 'g, 'x> = लिखें ('f ->' g -> 'x) ;; लेकिन यह ओकैमल वाक्यविन्यास सच नहीं हो सकता है। –

-1

तुम कर सकते हो, लेकिन आप एक चाल का एक सा बनाने की जरूरत है:

newtype Fix f = In{out:: f (Fix f)} 

आप Cata बाद में परिभाषित कर सकते हैं:

Cata :: (Functor f) => (f a -> a) -> Fix f -> a 
Cata f = f.(fmap (cata f)).out 

बस इतना ही functors, के लिए एक सामान्य catamorphism निर्धारित करेंगी कि आप अपनी खुद की सामग्री बनाने के लिए उपयोग कर सकते हैं। उदाहरण:

data ListFix a b = Nil | Cons a b 
data List a = Fix (ListFix a) 
instance functor (ListFix a) where 
fmap f Nil = Nil 
fmap f (Cons a lst) = Cons a (f lst) 
+2

प्रश्न ओकैम के मज़दूरों (हास्केल के मकसद से अलग) के बारे में है। – sdcvvc

+0

क्षमा करें, मैं सवाल को गलत तरीके से पढ़ता हूं। किसी भी मामले में, उम्मीद है कि इससे कोई भी संपर्क में आने में मदद करता है –