Hindley-Milner क्या है?


124

मुझे इस शब्द का सामना हिंडले-मिलनर से करना पड़ा , और मुझे यकीन नहीं है कि अगर इसका मतलब क्या है तो समझ लें।

मैंने निम्नलिखित पोस्ट पढ़ी हैं:

लेकिन विकिपीडिया में इस शब्द के लिए कोई एकल प्रविष्टि नहीं है जहां आम तौर पर मुझे संक्षिप्त विवरण मिलता है।
नोट - अब एक जोड़ा गया है

यह क्या है?
कौन सी भाषाएं और उपकरण इसे लागू करते हैं या इसका उपयोग करते हैं?
क्या आप कृपया संक्षिप्त उत्तर प्रस्तुत करेंगे?

जवाबों:


167

Hindley-Milner एक प्रकार की प्रणाली है जिसे रोजर Hindley (जो तर्क को देख रहा था) और बाद में रॉबिन मिलनर (जो प्रोग्रामिंग भाषाओं को देख रहा था) द्वारा स्वतंत्र रूप से खोजा गया है। Hindley-Milner के फायदे हैं

  • यह बहुरूपी कार्यों का समर्थन करता है; उदाहरण के लिए, एक फ़ंक्शन जो आपको तत्वों के प्रकार से स्वतंत्र सूची की लंबाई दे सकता है, या एक फ़ंक्शन बाइनरी-ट्री लुकअप करता है जो पेड़ में संग्रहीत कुंजी के प्रकार से स्वतंत्र है।

  • कभी-कभी एक फ़ंक्शन या मान में एक से अधिक प्रकार हो सकते हैं , जैसे कि लंबाई फ़ंक्शन के उदाहरण में: यह "पूर्णांक से पूर्णांक की सूची", "तार से पूर्णांक की सूची", "जोड़े से पूर्णांक की सूची", और इसी तरह हो सकता है। पर। इस मामले में, हिंडले-मिलनर प्रणाली का एक संकेत लाभ यह है कि प्रत्येक अच्छी तरह से टाइप किए गए शब्द का एक अनूठा "सर्वश्रेष्ठ" प्रकार है , जिसे प्रिंसिपल टाइप कहा जाता है । सूची-लंबाई फ़ंक्शन का मुख्य प्रकार "किसी aके aलिए, पूर्णांक की सूची से फ़ंक्शन " है। यहाँ aएक तथाकथित "टाइप पैरामीटर" है, जो लंबोदा कलन में स्पष्ट है लेकिन अधिकांश प्रोग्रामिंग भाषाओं में निहित हैपैरामीट्रिक बहुरूपता । (यदि आप एमएल में लंबाई फ़ंक्शन की परिभाषा लिखते हैं, तो आप टाइप पैरामीटर देख सकते हैं:

     fun 'a length []      = 0
       | 'a length (x::xs) = 1 + length xs
    
  • यदि किसी शब्द में एक हिंडले-मिलनर टाइप है, तो प्रोग्रामर द्वारा किसी भी प्रकार की घोषणा या अन्य एनोटेशन की आवश्यकता के बिना प्रिंसिपल प्रकार का अनुमान लगाया जा सकता है । (यह एक मिश्रित आशीर्वाद है, क्योंकि कोई भी व्यक्ति जो कभी भी अनाउंसमेंट के साथ एमएल कोड का एक बड़ा हिस्सा संभाल सकता है, उसे अटेस्ट कर सकता है।)

हिंडले-मिलनर लगभग हर सांख्यिकीय रूप से टाइप की जाने वाली कार्यात्मक भाषा के प्रकार का आधार है। आम उपयोग में ऐसी भाषाओं में शामिल हैं

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

टाइप की गई कार्यात्मक भाषाओं के आधार पर कई अन्य छोटी भाषाएँ और उपकरण Hindley-Milner का उपयोग करते हैं।

हिंडले-मिलनर सिस्टम एफ का प्रतिबंध है , जो अधिक प्रकार की अनुमति देता है लेकिन प्रोग्रामर द्वारा एनोटेशन की आवश्यकता होती है


2
@NormanRamsey मुझे पता है कि यह पुराना दुष्ट है, लेकिन यह स्पष्ट करने के लिए धन्यवाद कि मुझे किसने परेशान किया है: हर बार जब मैं hindley-milner प्रकार प्रणाली का उल्लेख करता हूं तो कोई व्यक्ति उस बिंदु के प्रकार के बारे में बात करने में झंकार करता है कि मैंने सवाल करना शुरू कर दिया है कि क्या HM एक प्रकार है प्रणाली या सिर्फ अनुमान एल्गोरिथ्म ... थैंक्यू मैं लोगों को इस बारे में गलत जानकारी देने के लिए विकिपीडिया का अनुमान लगाता हूं कि उन्होंने मुझे भ्रमित कर दिया है
जिमी होफा

1
यह बहुरंगी रूप से बहुरूपी क्यों है , केवल बहुरूपता के विपरीत? आपके द्वारा दिए गए किसी भी उदाहरण के साथ, मैं इसे एक उदाहरण के रूप में देखता हूं यदि बहुरूपता - जहां उपप्रकार का उपयोग उस सुपरपाइप के बजाय किया जा सकता है जो परिभाषा में निर्दिष्ट है, और पैरामीट्रिक बहुरूपता अला C C ++ नहीं जहां वास्तविक प्रकार प्रोग्रामर द्वारा निर्दिष्ट करने के लिए निर्दिष्ट किया गया है नया समारोह।
corazza

1
@ जोकोरा: कुछ साल देर से, लेकिन भविष्य के पाठकों के लाभ के लिए: इसे पैरामीट्रिक कहा जाता है बहुरूपता की संपत्ति की वजह से parametricity है, जो किसी भी प्रकार आप में प्लग, एक समारोह की तरह के सभी उदाहरणों के लिए साधन length :: forall a. [a] -> Intही व्यवहार करना चाहिए की परवाह किए बिना a-यह न झिल्लड़; आप इसके बारे में कुछ नहीं जानते हैं। instanceofजब तक आप अतिरिक्त प्रकार की बाधाएं (हास्केल टाइपक्लैस) नहीं जोड़ते हैं तब तक कोई (जावा जेनरिक) और न ही "डक टाइपिंग" (C ++ टेम्प्लेट) होता है। पैरामीट्रिकिटी के साथ आप कुछ अच्छे प्रमाण प्राप्त कर सकते हैं कि एक फ़ंक्शन क्या कर सकता है / नहीं कर सकता है।
जॉन प्यार्डी

8

आप Google विद्वान या CiteSeer - या अपने स्थानीय विश्वविद्यालय पुस्तकालय का उपयोग करके मूल कागजात ढूंढने में सक्षम हो सकते हैं। पहला काफी पुराना है कि आपको जर्नल की बाध्य प्रतियां ढूंढनी पड़ सकती हैं, मैं इसे ऑनलाइन नहीं पा सकता था। लिंक जो मुझे दूसरे के लिए मिला था वह टूट गया था, लेकिन अन्य हो सकता है। आप निश्चित रूप से कागजात खोजने में सक्षम होंगे जो इन का हवाला देते हैं।

हिंडले, रोजर जे, कॉम्बिनेटर लॉजिक में किसी वस्तु की प्रमुख प्रकार की योजना , अमेरिकी गणितीय सोसायटी के लेन-देन, 1969।

मिलनर, रॉबिन, ए थ्योरी ऑफ़ टाइप पॉलीमोर्फिज़्म , जर्नल ऑफ़ कंप्यूटर एंड सिस्टम साइंसेस, 1978।


2
उत्तरार्द्ध यहाँ पाया जा सकता है: citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.67.5276
मैग्नस


6

सी # में सरल हिंडले-मिलनर प्रकार के कार्यान्वयन

हिंडले-मिलनर प्रकार का अनुमान (लिस्प-ईश) एस-एक्सप्रेशन, सी # की 650 लाइनों के नीचे

ध्यान दें कि कार्यान्वयन केवल 270 या C # की रेखाओं (एल्गोरिथम डब्ल्यू उचित और कुछ डेटा संरचनाओं को समर्थन करने के लिए, वैसे भी) की सीमा में है।

उपयोग अंश:

    // ...

    var syntax =
        new SExpressionSyntax().
        Include
        (
            // Not-quite-Lisp-indeed; just tolen from our host, C#, as-is
            SExpressionSyntax.Token("\\/\\/.*", SExpressionSyntax.Commenting),
            SExpressionSyntax.Token("false", (token, match) => false),
            SExpressionSyntax.Token("true", (token, match) => true),
            SExpressionSyntax.Token("null", (token, match) => null),

            // Integers (unsigned)
            SExpressionSyntax.Token("[0-9]+", (token, match) => int.Parse(match)),

            // String literals
            SExpressionSyntax.Token("\\\"(\\\\\\n|\\\\t|\\\\n|\\\\r|\\\\\\\"|[^\\\"])*\\\"", (token, match) => match.Substring(1, match.Length - 2)),

            // For identifiers...
            SExpressionSyntax.Token("[\\$_A-Za-z][\\$_0-9A-Za-z\\-]*", SExpressionSyntax.NewSymbol),

            // ... and such
            SExpressionSyntax.Token("[\\!\\&\\|\\<\\=\\>\\+\\-\\*\\/\\%\\:]+", SExpressionSyntax.NewSymbol)
        );

    var system = TypeSystem.Default;
    var env = new Dictionary<string, IType>();

    // Classic
    var @bool = system.NewType(typeof(bool).Name);
    var @int = system.NewType(typeof(int).Name);
    var @string = system.NewType(typeof(string).Name);

    // Generic list of some `item' type : List<item>
    var ItemType = system.NewGeneric();
    var ListType = system.NewType("List", new[] { ItemType });

    // Populate the top level typing environment (aka, the language's "builtins")
    env[@bool.Id] = @bool;
    env[@int.Id] = @int;
    env[@string.Id] = @string;
    env[ListType.Id] = env["nil"] = ListType;

    //...

    Action<object> analyze =
        (ast) =>
        {
            var nodes = (Node[])visitSExpr(ast);
            foreach (var node in nodes)
            {
                try
                {
                    Console.WriteLine();
                    Console.WriteLine("{0} : {1}", node.Id, system.Infer(env, node));
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            Console.WriteLine();
            Console.WriteLine("... Done.");
        };

    // Parse some S-expr (in string representation)
    var source =
        syntax.
        Parse
        (@"
            (
                let
                (
                    // Type inference ""playground""

                    // Classic..                        
                    ( id ( ( x ) => x ) ) // identity

                    ( o ( ( f g ) => ( ( x ) => ( f ( g x ) ) ) ) ) // composition

                    ( factorial ( ( n ) => ( if ( > n 0 ) ( * n ( factorial ( - n 1 ) ) ) 1 ) ) )

                    // More interesting..
                    ( fmap (
                        ( f l ) =>
                        ( if ( empty l )
                            ( : ( f ( head l ) ) ( fmap f ( tail l ) ) )
                            nil
                        )
                    ) )

                    // your own...
                )
                ( )
            )
        ");

    // Visit the parsed S-expr, turn it into a more friendly AST for H-M
    // (see Node, et al, above) and infer some types from the latter
    analyze(source);

    // ...

... कौन सी पैदावार:

id : Function<`u, `u>

o : Function<Function<`z, `aa>, Function<`y, `z>, Function<`y, `aa>>

factorial : Function<Int32, Int32>

fmap : Function<Function<`au, `ax>, List<`au>, List<`ax>>

... Done.

ब्रायन मैककेना के जावास्क्रिप्ट कार्यान्वयन को भी देखेंबिटबकैट पर को , जो आरंभ करने में मदद करता है (मेरे लिए काम किया)।

'HTH,

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.