2011-02-06 19 views
11

[यह सवाल "असली दुनिया हास्केल" में अध्याय 9 से प्रेरित है]

यहाँ एक सरल समारोह (अनिवार्य करने के लिए कटौती) है:

saferOpenFile path = handle (\_ -> return Nothing) $ do 
     h <- openFile path ReadMode 
     return (Just h) 

मुझे लगता है कि $ आवश्यकता क्यों है?

को संभालने के लिए दूसरा तर्क एक करते ब्लॉक नहीं है, तो मैं इसे जरूरत नहीं है। निम्नलिखित काम करता है ठीक:

handle (\_ -> putStrLn "Error calculating result") (print x) 

जब मैं $ संकलन को दूर करने की कोशिश की असफल रहा। मैं

saferOpenFile path = handle (\_ -> return Nothing) (do 
     h <- openFile path ReadMode 
     return (Just h)) 

मैं समझ सकता हूँ कि, अगर मैं स्पष्ट रूप से कोष्ठक जोड़ने यह काम करने के लिए प्राप्त कर सकते हैं यानी, लेकिन मुझे लगता है मैं उम्मीद कर रहा हूँ कि यह सोचना चाहिए जब हास्केल do हिट "मैं एक ब्लॉक शुरू कर", और चीजों को तोड़ने के लिए हमें $ को स्पष्ट रूप से रखना नहीं चाहिए।

मैं भी अगली पंक्ति में करते ब्लॉक धक्का, इस तरह के बारे में सोचा:

saferOpenFile path = handle (\_ -> return Nothing) 
    do 
    h <- openFile path ReadMode 
    return (Just h) 

लेकिन यह है कि कोष्ठक के बिना या तो काम नहीं करता। यही कारण है कि मुझे confuses, क्योंकि निम्न काम करता है:

add a b = a + b 

addSeven b = add 7 
    b 

मुझे यकीन है कि मैं सिर्फ बिंदु जहां मैं "के रूप में है कि बस यह सब कैसे कर मुहावरेदार हास्केल लिखने" इसे स्वीकार पहुँचेंगे हूँ, लेकिन किसी को भी किसी भी परिप्रेक्ष्य देने के लिए है ? अग्रिम में धन्यवाद।

+0

क्षमा करें, दोस्तों, मुझे स्टैक ओवरफ्लो बहुत अच्छी तरह से पता नहीं है। कोड सिर्फ कचरा है। (क्यों कोई "पूर्वावलोकन प्रश्न" नहीं है)। मैं इसे फिर से पोस्ट करने की कोशिश करूंगा। – Jonathan

+0

संपादक टूलबार पर बस "कोड" बटन दबाएं (यह ब्रेसिज़ की एक जोड़ी जैसा दिखता है)। साथ ही, पूर्वावलोकन सही समय में अपडेट किया गया है, वास्तविक समय में अपडेट किया गया है ... – Jon

+1

आह, नोस्क्रिप्ट को एक और डोमेन की अनुमति देने की आवश्यकता है! यह अभी ठीक दिखता है। धन्यवाद, जॉन! – Jonathan

उत्तर

6

Haskell 2010 report, do desugars इस तरह के अनुसार:

do {e;stmts} = e >>= do {stmts}

do {p <- e; stmts} = let ok p = do {stmts} 
         ok _ = fail "..." 
        in e >>= ok 

दूसरे मामले के लिए, यह यह इस (और प्रदर्शन-परक प्रयोजनों के लिए आसान) की तरह desugaring लिखने के लिए एक ही है:

do {p <- e; stmts} = e >>= (\p -> do stmts)

तो मान लीजिए कि आप लिखना इस:

-- to make these examples shorter 
saferOpenFile = f 
o = openFile 

f p = handle (\_ -> return Nothing) do 
    h <- o p ReadMode 
    return (Just h) 

यह इस लिए desugars:

f p = handle (\_ -> return Nothing) (o p ReadMode) >>= (\h -> return (Just h)) 

कौन इस रूप में ही है:

f p = (handle (\_ -> return Nothing) (o p ReadMode)) >>= (\h -> return (Just h)) 

हालांकि आप शायद यह मतलब करने के लिए के लिए लक्षित यह:

handle (\_ -> return Nothing) ((o p ReadMode) >>= (\h -> return (Just h))) 

tl; dr - वाक्यविन्यास कब खोला जाता है, यह पूरे कथन को संश्लेषित नहीं करता है जैसा कि आपको लगता है कि इसे (हास्केल 2010 के रूप में) चाहिए।

यह उत्तर केवल AFAIK है और

  1. सही
  2. पुरानी किसी दिन हो सकता है अगर यह सही है

नोट नहीं हो सकता है: अगर तुम मुझे करने के लिए कहते हैं कि "लेकिन वास्तविक desugaring का उपयोग करता है एक 'लेट' कथन जो e >>= ok को समूहित करना चाहिए, है ना? ", तो मैं टीएल के रूप में वही जवाब दूंगा; कथन के लिए डॉ: यह आपके जैसे सोचने वाले समूह/समूह को संश्लेषित नहीं करता है।

+0

का उपयोग किया जा रहा है तो मुझे लगता है कि रिपोर्ट इस उत्तर को निश्चित बनाती है। मुझे लगता है कि मुझे बस हास्केल के लैम्ब्डा-कैलकुस स्टाइल फ़ंक्शन एप्लिकेशन में उपयोग करने में कठिन समय हो रहा है, जिसे मैंने सोचा था कि मैं था। – Jonathan

+0

यह वास्तव में इस उत्तर का एक संयोजन है और कैलम है जो आपके प्रश्न का पूरा उत्तर खींचता है। यह समझाने के लिए कि '$' की आवश्यकता क्यों है और दूसरा यह समझाने के लिए कि यह क्या करता है। –

+2

यह उत्तर नहीं है। डी-शर्करा हमेशा तैयार अमूर्त वाक्यविन्यास पेड़ पर काम करता है, जिसका अर्थ है कि यह 'पूरी तरह से संश्लेषित' इनपुट लेता है और 'पूरी तरह से संश्लेषित' आउटपुट उत्पन्न करता है। यह परिभाषित नहीं करता कि वैध इनपुट कैसा दिखता है, या जब आपको कोष्ठक की आवश्यकता होती है। (यह लिस्प मैक्रोस की तरह लिस्प रीडर मैक्रोज़ या सी के टोकन अनुक्रम मैक्रोज़ की तरह परिभाषित किया गया है)। –

10

इस आपरेशन के हास्केल के आदेश के कारण है। फंक्शन एप्लिकेशन कसकर बांधता है, जो भ्रम का स्रोत हो सकता है। उदाहरण के लिए:

add a b = a + b 
x = add 1 add 2 3 

हास्केल इस रूप में व्याख्या: समारोह 1 के लिए आवेदन किया जोड़ते हैं, और समारोह जोड़ें। शायद यह नहीं है कि प्रोग्रामर का इरादा क्या है। हास्केल दूसरे तर्क के लिए न्यूम की अपेक्षा करने के बारे में शिकायत करेगा, लेकिन इसके बजाय एक समारोह प्राप्त कर रहा है।

1) अभिव्यक्ति parenthesized जा सकता है::

x = add 1 (add 2 3) 

कौन सा हास्केल के रूप में व्याख्या करेगा:

दो समाधान कर रहे हैं समारोह, 1 करने के लिए लागू जोड़ने तो की मूल्य जोड़ने 2 3.

लेकिन नेस्टिंग बहुत गहरा हो जाता है, तो यह भ्रामक है, इसलिए दूसरा समाधान प्राप्त कर सकते हैं।

2) $ ऑपरेटर:

x = add 1 $ add 2 3 

$ अपने तर्कों को एक समारोह के लागू होने वाला एक ऑपरेटर है। हास्केल इसे इस प्रकार पढ़ता है: फ़ंक्शन (जोड़ें 1) 2 के मान पर लागू होता है 3. याद रखें कि हास्केल में, फ़ंक्शंस आंशिक रूप से लागू किया जा सकता है, इसलिए (1 जोड़ें) एक तर्क का एक पूर्ण मान्य कार्य है।

$ ऑपरेटर इस्तेमाल किया जा सकता कई बार:

x = add 1 $ add 2 $ add 3 4 

कौन सा समाधान आप लेने निर्धारित किया जाएगा जिसके द्वारा आपको लगता है एक विशेष संदर्भ में अधिक पठनीय है।

+3

धन्यवाद, कॉलम। मैंने अनुमान लगाया कि ($) ज्यादातर वाक्यविन्यास के बारे में था जब मैंने इसकी परिभाषा लिखने की कोशिश की और ($) f x = f x के साथ आया। मेरे सीमित स्रोतों से ऐसा लगता है जैसे हास्केलर्स वास्तव में माता-पिता से बचना पसंद करते हैं, जहां संभव हो। मुझे लगता है कि यह अन्य भाषाओं से आ रहा है, जहां मैं जोड़ने (1, जोड़ने (3, 4)) पढ़ने में अच्छा हूं। खासतौर पर जब – Jonathan

10

यह वास्तव में do -notation के लिए बिल्कुल विशिष्ट नहीं है। आप print if x then "Yes" else "No" या print let x = 1+1 in x*x जैसी चीजें भी नहीं लिख सकते हैं।

आप chapter 3 of the Haskell Report की शुरुआत में व्याकरण परिभाषा से इस की पुष्टि कर सकते हैं: एक do अभिव्यक्ति या एक सशर्त या एक let अभिव्यक्ति एक lexp है, लेकिन समारोह आवेदन के तर्क एक Aexp, और एक lexp है आमतौर पर एएक्सपी के रूप में मान्य नहीं है।

यह आपको नहीं बताता कि रिपोर्ट में यह विकल्प क्यों बनाया गया था। अगर मुझे लगता है कि, मुझे अनुमान लगाया जा सकता है कि do और उसके ब्लॉक के बीच बाध्यकारी करने के लिए उपयोगी नियम "फ़ंक्शन एप्लिकेशन किसी अन्य चीज़ से कड़ा बांधता है" का विस्तार करना है।लेकिन मुझे नहीं पता कि वह मूल प्रेरणा थी या नहीं। (मुझे print if x then ... जैसे अस्वीकार रूपों को पढ़ने के लिए मुश्किल लगता है, लेकिन ऐसा इसलिए हो सकता है क्योंकि मुझे हास्केल स्वीकार करने वाले कोड को पढ़ने के लिए उपयोग किया जाता है।)

संबंधित मुद्दे