2012-06-03 11 views
15

इस दिन एक दिन के लिए मेरे सिर खरोंच कर रहा है।सशर्त में मोनाडिक अभिव्यक्तियां - जीएचसी संकलन, कैबल

मैं अपने कोड में कुछ कार्यों कि इस तरह दिखना है:

function :: IO (Maybe Whatever) 
function = do 
    monadFun 
    yaySomeIO 
    status <- maybeItWillFail 
    if checkStatus status -- Did we succeed? 
    then monadTime >>= return . Just . processItPurely 
    else return Nothing 

GHCi लोड और कोई समस्या नहीं के साथ सहभागी इस चलेंगे, और GHC यह खुशी से संकलित कर देगा।

myProgram.hs:94:16: 
Unexpected semi-colons in conditional: 
    if checkStatus status; then monadTime >>= return . Just . processItPurely; else return Nothing 

Perhaps you meant to use -XDoAndIfThenElse? 

और जो कुछ भी इस -XDoAndIfThenElse विकल्प है, मैं किसी भी दस्तावेज में कहीं भी यह के निशान खोजने के लिए प्रतीत नहीं कर सकते हैं: कबाल के माध्यम से इस चल रहा है, फिर भी, मुझे इस देता है। कैबल क्यों है (या इस बिंदु से यह ghc है?) अर्ध-कॉलन का उपयोग करने के लिए मुझ पर चिल्लाना है कि आईटी पहले स्थान पर रखता है? या यदि मोनैडिक एक्सप्रेशन का उपयोग कर रहे हैं तो क्या बयान सिर्फ एक बुरा विचार है?

ध्यान दें कि कबाल इस बारे में बिल्कुल भी शिकायत नहीं करता है:

case checkStatus status of 
    True -> monadTime >>= return . Just . processItPurely 
    _ -> return Nothing 

... इस को छोड़कर नरक के रूप में बदसूरत है और मैं अपने कोड में यह रखना चाहता हूँ कभी नहीं होगा। क्या कोई मुझे बता सकता है कि क्या हो रहा है? कृपया और अग्रिम धन्यवाद।

उत्तर

27

"सही" एक do -block में if -expressions इंडेंट के रास्ते इस तरह if से आगे else और then लाइनों इंडेंट करने के लिए, है।

function = do 
    monadFun 
    yaySomeIO 
    status <- maybeItWillFail 
    if checkStatus status -- Did we succeed? 
     then monadTime >>= return . Just . processItPurely 
     else return Nothing 

इसका कारण यह है एक do ब्लॉक में खरोज की एक ही राशि के साथ लाइनों सामान्य रूप से अलग बयान माना जाता है।

हालांकि, DoAndIfThenElse नामक एक एक्सटेंशन है जो आपको इसे लिखने की अनुमति देगा। यह एक्सटेंशन हास्केल 2010 में मानक बनाया गया था, यही कारण है कि जीएचसी इसे डिफ़ॉल्ट रूप से सक्षम बनाता है।

कैबल आपको इन चीजों के बारे में अधिक स्पष्ट होने की आवश्यकता है, इसलिए इसे कैबल में उपयोग करने के लिए, आपको या तो अपने .cabal फ़ाइल में इसका उल्लेख करना होगा या अपने मॉड्यूल के शीर्ष पर {-# LANGUAGE DoAndIfThenElse #-} जोड़ें।

+3

धन्यवाद, मैं केवल इंडेंट्स को आवश्यकतानुसार जोड़ दूंगा! –

6

यह आपके प्रश्न का सीधा जवाब नहीं है, लेकिन आप MaybeT का लाभ उठाकर अगर कथन को खत्म कर सकते हैं। इसके अलावा, foo >>= return . barbar <$> foo जैसा ही है। (<$>Control.Applicative से है, और fmap रूप में ही है)

function :: MaybeT IO Whatever 
function = do 
    lift monadFun 
    lift yaySomeIO 
    status <- lift maybeItWillFail 
    guard (checkStatus status) 
    processItPurely <$> lift monadTime 

केवल झुंझलाहट lift के नि: शुल्क छिड़काव है, लेकिन वहाँ तरीके उन में से छुटकारा पाने के लिए कर रहे हैं।

+1

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

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