हास्कल्स कमजोर सिर सामान्य रूप


9

मैं कुछ चिड़चिड़ी चीजों पर ठोकर खाई है। मुझे पता है कि हैक्सेल कमजोर सिर सामान्य रूप (WHNF) के साथ काम करता है और मुझे पता है कि यह क्या है। निम्नलिखित कोड को ghci में टाइप करना (मैं कमांड का उपयोग कर रहा हूं: स्प्रिंट जो कि मेरी जानकारी के लिए WHNF के लिए अभिव्यक्ति को कम करता है:

let intlist = [[1,2],[2,3]]
:sprint intlist

देता है intlist = _यह बनाता है पूरी तरह से मेरे लिए भावना।

let stringlist = ["hi","there"]
:sprint stringlist 

देता है stringlist = [_,_] यह पहले से ही मुझे confuses। परन्तु फिर:

let charlist = [['h','i'], ['t','h','e','r','e']]
:sprint charlist

आश्चर्यजनक रूप से देता है charlist = ["hi","there"]

जहाँ तक मेरा हास्केल समझ में आया, तार जो प्रकार की जाँच करके इस बात की पुष्टि होने लगता है वर्ण की सूची, की तुलना में और कुछ नहीं कर रहे हैं "hi" :: [Char]और ['h','i'] :: [Char]

मैं भ्रमित हूं, क्योंकि मेरी समझ में उपरोक्त तीनों उदाहरण कमोबेश एक ही (सूचियों की सूची) हैं और इसलिए उसी WHNF को कम करना चाहिए, अर्थात _। मैं क्या खो रहा हूँ?

धन्यवाद


यह संबंधित प्रतीत होता है
बर्गी

@ बर्गी उन सवालों से संबंधित हैं, लेकिन न तो यह पता लगता है कि क्यों "bla"और ['b','l','a']अलग तरीके से सामने आएंगे।
लेफ्टरनबाउट

@leftractionabout क्योंकि "bla"अतिभारित किया जा सकता है, लेकिन ['b','l','a']a String/ होना जाना जाता है [Char]?
बरगी

1
@ बर्गी मैंने उसके बारे में भी सोचा था, लेकिन यह वास्तव में प्रशंसनीय नहीं है क्योंकि ['b', 'l', 'a']यह भी अतिभारित हो सकता है , और इसी तरह "bla"केवल अतिभारित होने -XOverloadedStringsपर चालू हो जाता है।
लेफ्टनैबाउट

2
पार्सर से संबंधित, संभवतः GHCi के लिए विशिष्ट है? (मुझे नहीं पता कि आप जीएचसी-संकलित कोड में WHNF के लिए कैसे परीक्षण करते हैं।) उद्धरण स्वयं ट्रिगर प्रतीत होते हैं।
13

जवाबों:


5

ध्यान दें कि :sprintहै नहीं WHNF को एक अभिव्यक्ति को कम। यदि यह किया जाता है, तो निम्नलिखित इसके 4बजाय देगा _:

Prelude> let four = 2 + 2 :: Int
Prelude> :sprint four
four = _

बल्कि, :sprintएक बंधन का नाम लेता है, बंधन के मूल्य के आंतरिक प्रतिनिधित्व का पता _लगाता है , और पहले से ही मूल्यांकन किए गए थ्रेश (यानी, निलंबित आलसी फ़ंक्शन ) के लिए एक प्लेसहोल्डर के रूप में उपयोग करते हुए पहले से ही "मूल्यांकन किए गए भागों" (यानी, निर्माण वाले हिस्से) दिखाता है। कॉल)। यदि मान पूरी तरह से अविकसित है, तो कोई मूल्यांकन नहीं किया जाएगा, यहां तक ​​कि WHNF तक भी नहीं। (और यदि मूल्य का पूरी तरह से मूल्यांकन किया जाता है, तो आपको वह मिलेगा, न कि केवल WHNF।)

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

यदि आप वास्तव में समझना चाहते हैं कि क्या :sprintकर रहे हैं, तो आप GHCi में कुछ झंडे को चालू कर सकते हैं यह देखने के लिए कि वास्तव में अभिव्यक्ति को कैसे संभाला जा रहा है और, इसलिए, अंततः बायटेकोड के लिए संकलित किया गया है:

> :set -ddump-simpl -dsuppress-all -dsuppress-uniques

इस के बाद, हम कारण अपने को देख सकते हैं intlistदेता है _:

> let intlist = [[1,2],[2,3]]
==================== Simplified expression ====================
returnIO
  (: ((\ @ a $dNum ->
         : (: (fromInteger $dNum 1) (: (fromInteger $dNum 2) []))
           (: (: (fromInteger $dNum 2) (: (fromInteger $dNum 3) [])) []))
      `cast` <Co:10>)
     [])

आप returnIOबाहरी :कॉल को अनदेखा कर सकते हैं , और उस भाग पर ध्यान केंद्रित कर सकते हैं जो इसके साथ शुरू होता है((\ @ a $dNum -> ...

यहाँ बाधा के $dNumलिए शब्दकोश है Num। इसका मतलब यह है कि उत्पन्न कोड ने वास्तविक प्रकार aको अभी तक हल नहीं किया है Num a => [[a]], इसलिए संपूर्ण अभिव्यक्ति को अभी भी एक उपयुक्त Numप्रकार के लिए एक फ़ंक्शन कॉल (शब्दकोश के लिए) के रूप में दर्शाया गया है । दूसरे शब्दों में, यह एक अनवैलिटेड थंक है, और हमें मिलता है:

> :sprint intlist
_

दूसरी ओर, प्रकार निर्दिष्ट करें Int, और कोड पूरी तरह से अलग है:

> let intlist = [[1::Int,2],[2,3]]
==================== Simplified expression ====================
returnIO
  (: ((: (: (I# 1#) (: (I# 2#) []))
         (: (: (I# 2#) (: (I# 3#) [])) []))
      `cast` <Co:6>)
     [])

और इसलिए :sprintउत्पादन है:

> :sprint intlist
intlist = [[1,2],[2,3]]

इसी तरह, शाब्दिक तार और पात्रों की स्पष्ट सूची में पूरी तरह से अलग प्रतिनिधित्व है:

> let stringlist = ["hi", "there"]
==================== Simplified expression ====================
returnIO
  (: ((: (unpackCString# "hi"#) (: (unpackCString# "there"#) []))
      `cast` <Co:6>)
     [])

> let charlist = [['h','i'], ['t','h','e','r','e']]
==================== Simplified expression ====================
returnIO
  (: ((: (: (C# 'h'#) (: (C# 'i'#) []))
         (: (: (C# 't'#)
               (: (C# 'h'#) (: (C# 'e'#) (: (C# 'r'#) (: (C# 'e'#) [])))))
            []))
      `cast` <Co:6>)
     [])

और :sprintआउटपुट में भिन्नता कलाकृतियों का प्रतिनिधित्व करती है, जो अभिव्यक्ति के कुछ हिस्सों में GHCi मूल्यांकन किए गए (स्पष्ट :कंस्ट्रक्टर) बनाम unpackCString#अनवैल्युएटेड ( थ्रक्स) मानते हैं।

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