2011-11-17 12 views
30

मैं हास्केल के लिए बिल्कुल नया हूं और धीरे-धीरे यह विचार प्राप्त कर रहा हूं कि मोनाड के अस्तित्व में कुछ गड़बड़ है। रियल वर्ल्ड हास्केल warns against its use ("एक बार फिर, हम अनुशंसा करते हैं कि आप लगभग असफल होने से बचें!")। मैंने अभी देखा है कि रॉस पैटरसन ने इसे "एक वार्ट, डिजाइन पैटर्न नहीं" कहा है back in 2008 (और उस धागे में काफी कुछ समझौता हुआ)।क्या मुझे मोनाड का उपयोग करने से बचने चाहिए?

डॉ राल्फ लामेल talk on the essence of functional programming देखकर, मैंने एक संभावित तनाव को समझना शुरू कर दिया जो मोनाड को विफल कर सकता है। व्याख्यान में, आधार मोनैडिक पार्सर (लॉगिंग, राज्य इत्यादि) के लिए विभिन्न मोनैडिक प्रभाव जोड़ने के बारे में राल्फ वार्ता। कई प्रभावों को आधार पार्सर में बदलने और कभी-कभी उपयोग किए जाने वाले डेटा प्रकारों में परिवर्तन की आवश्यकता होती है। मुझे लगा कि सभी मोनैड के लिए 'असफल' का जोड़ा एक समझौता हो सकता है क्योंकि 'असफल' इतना आम है और आप जितना संभव हो सके 'आधार' पार्सर (या जो कुछ भी) में परिवर्तन से बचना चाहते हैं। निस्संदेह, कुछ प्रकार की 'असफल' पार्सर्स के लिए समझ में आता है लेकिन हमेशा नहीं, कहें, राज्य के बारे में पूछें/प्राप्त करें या रीडर के स्थानीय/पूछें।

मुझे बताएं कि क्या मैं गलत ट्रैक पर जा सकता हूं।

क्या मुझे मोनाड का उपयोग करने से बचने में असफल होना चाहिए? मोनाड के विकल्प क्या असफल हैं? क्या कोई वैकल्पिक मोनैड पुस्तकालय हैं जिनमें "डिज़ाइन वार्ट" शामिल नहीं है? मैं इस डिजाइन निर्णय के आसपास के इतिहास के बारे में और कहां पढ़ सकता हूं?

+4

[रियल वर्ल्ड हास्केल कहते हैं] (http://book.realworldhaskell.org/read/monads.html#monads.monad.fail) "[कई monads में] 'विफल' 'त्रुटि' का उपयोग करता है। 'त्रुटि' को कॉल करना आमतौर पर अत्यधिक अवांछनीय है, क्योंकि यह एक अपवाद फेंकता है कि कॉलर्स या तो पकड़ नहीं सकते हैं या उम्मीद नहीं करेंगे। " – Miikka

+3

संक्षिप्त उत्तर: हाँ। –

+2

मेरा मानना ​​है कि पैटर्न विफलताओं को संभालने के लिए "विफल" की आवश्यकता होती है जब आप ऐसा करते हैं: "बस x <- somethingReturningIoMaybe"। –

उत्तर

27

कुछ monads एक समझदार विफलता तंत्र है, उदा। टर्मिनल इकाई:

data Fail x = Fail 

कुछ monads एक समझदार विफलता तंत्र की जरूरत नहीं है (undefined समझदार नहीं है), उदा प्रारंभिक इकाई:

data Return x = Return x 

इस संदर्भ में, यह स्पष्ट रूप से एक fail विधि के लिए सभी monads की आवश्यकता के लिए एक मस्सा है। यदि आप ऐसे प्रोग्राम लिख रहे हैं जो मोनैड (Monad m) => पर अमूर्त हैं, तो उस सामान्य m की fail विधि का उपयोग करना बहुत स्वस्थ नहीं है। इसके परिणामस्वरूप आप एक मोनैड के साथ तत्काल कार्य कर सकते हैं जहां fail वास्तव में मौजूद नहीं होना चाहिए।

मैं fail का उपयोग कर (विशेष रूप से परोक्ष रूप से, Pat <- computation मिलान करके) के लिए कम आपत्तियों को देखने जब एक विशिष्ट इकाई जो के लिए एक अच्छा fail व्यवहार स्पष्ट रूप से निर्दिष्ट किया गया है में काम कर रहे। ऐसे कार्यक्रम उम्मीदवारों को पुराने अनुशासन में वापसी से बचेंगे जहां नॉनट्रिविअल पैटर्न मिलान ने MonadZero की मांग Monad की बजाय बनाई थी।

कोई तर्क दे सकता है कि बेहतर अनुशासन हमेशा विफलता-मामलों का इलाज करने के लिए है। मैं इस स्थिति को दो मायने रखता हूं: (1) कि मोनैडिक प्रोग्रामिंग का बिंदु इस तरह के अव्यवस्था से बचने के लिए है, और (2) कि एक monadic गणना के परिणाम पर केस विश्लेषण के लिए वर्तमान नोटेशन इतना भयानक है। एसएचई की अगली रिलीज नोटेशन (अन्य प्रकारों में भी पाया जाता है)

case <- computation of 
    Pat_1 -> computation_1 
    ... 
    Pat_n -> computation_n 

जो थोड़ा सा मदद कर सकता है।

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

तो, यह एक बेहतर काम कर सकता है, लेकिन कम से कम, fail केवल विशिष्ट मोनैड के लिए उपयोग करें जो एक समझदार कार्यान्वयन प्रदान करते हैं, और 'अपवाद' को सही तरीके से संभालते हैं।

+0

क्षमा करें, वह "वह" क्या है जिसका आप उल्लेख करते हैं? –

+1

यह स्ट्रैथक्लाइड हास्केल एन्हांसमेंट है, जो मेरे प्रीप्रोसेसर प्रयोगात्मक सुविधाओं का समर्थन करता है (नकली आश्रित प्रकार, ज्यादातर)। लेकिन इन दिनों, जीएचसी में उस कार्यक्षमता को अपनाने के द्वारा SHE को अनावश्यक बना दिया गया है। – pigworker

24

हास्केल 1.4 (1 99 7) में fail नहीं था। इसके बजाए, MonadZero प्रकार वर्ग था जिसमें zero विधि थी। अब, पैटर्न मिलान विफलता को इंगित करने के लिए do नोटेशन zero का उपयोग किया गया; इससे लोगों को आश्चर्य हुआ: चाहे उनके फ़ंक्शन को Monad या MonadZero की आवश्यकता हो, इस पर निर्भर करता है कि उन्होंने do नोटेशन का उपयोग कैसे किया।

जब हास्केल 98 को थोड़ी देर बाद डिजाइन किया गया था, तो उन्होंने नौसिखिए को प्रोग्रामिंग को सरल बनाने के लिए कई बदलाव किए। उदाहरण के लिए, मोनद समझों को सूची समझ में बदल दिया गया था। इसी प्रकार, do प्रकार वर्ग समस्या को हटाने के लिए, MonadZero कक्षा हटा दी गई थी; do के उपयोग के लिए, विधि fail को Monad में जोड़ा गया था; और zero के अन्य उपयोगों के लिए, mzero विधि MonadPlus में जोड़ा गया था।

मुझे लगता है कि fail को स्पष्ट रूप से किसी भी चीज़ के लिए उपयोग नहीं किया जाना चाहिए; इसका एकमात्र उद्देश्य do नोटेशन के अनुवाद में है। फिर भी, मैं अक्सर शरारती हूं और fail का भी स्पष्ट रूप से उपयोग करता हूं।

आप मूल 1.4 और 98 रिपोर्ट here तक पहुंच सकते हैं। मुझे यकीन है कि परिवर्तन की ओर अग्रसर चर्चा कुछ ईमेल सूची अभिलेखागार में पाई जा सकती है, लेकिन मेरे पास लिंक आसान नहीं हैं।

+0

का उपयोग करना चाहिए" मैं स्वयं अक्सर शरारती हूं और स्पष्ट रूप से 'असफल' का उपयोग करता हूं। अक्सर? के बारे में बताएं। –

+6

@ डैनबर्टन: व्याख्या करने के लिए क्या है? यदि मैं एक monadic संदर्भ में हूँ, तो मैं विफलता सिग्नल करने के लिए 'असफल' का उपयोग करता हूं, जब तक कि मुझे किसी अन्य तंत्र का उपयोग करने की विशिष्ट आवश्यकता न हो। – ibid

+0

धन्यवाद। इतिहास के बारे में सुनना अच्छा है। मुझे नहीं पता था कि हास्केल मूल रूप से केवल नोटेशन (सूची समझ के बिना) था। मुझे मेलिंग सूची संग्रह में एक दिलचस्प धागा मिला http://www.mail-archive.com/[email protected]/msg03002.html –

6

मैं जहां भी संभव हो मोनाड से बचने की कोशिश करता हूं, और आपके परिस्थिति के आधार पर असफल होने के कई तरीके हैं। एडवर्ड यांग ने 8 ways to report errors in Haskell revisited शीर्षक वाले लेख में अपने ब्लॉग पर एक अच्छा अवलोकन लिखा है।

सारांश में, अलग अलग तरीकों से त्रुटियों की रिपोर्ट है कि वह पहचानती है कर रहे हैं:

  1. उपयोग त्रुटि
  2. उपयोग हो सकता है कि एक
  3. उपयोग या तो स्ट्रिंग एक
  4. उपयोग इकाई और 1- सामान्यीकरण करने के लिए असफल 3
  5. MonadError और कस्टम त्रुटि प्रकार
  6. आईओ monad
  7. में फेंक का उपयोग करें
  8. उपयोग ioError और पकड़
  9. इकाई ट्रांसफार्मर के साथ जाओ पागल
  10. जांचे हुए अपवादों
  11. विफलता
इनमें से

, मैं विकल्प 3, Either e b साथ उपयोग करने के लिए करता है, तो मुझे पता है कि त्रुटि को संभालने के लिए परीक्षा की जाएगी , लेकिन थोड़ा और संदर्भ की जरूरत है।

+1

या 'शायद' ... किसी का उपयोग करना अच्छा है। एक लाइब्रेरी का उपयोग करके यह कष्टप्रद है जो किसी भी और एक लाइब्रेरी का उपयोग करता है जो शायद उसी कोड में उपयोग करता है। मोनाड ट्रांसफार्मर काफी अच्छे नहीं हैं ... – alternative

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