2012-12-07 20 views
14

के भीतर से लॉग इन करना मैं कार्यात्मक प्रतिमान के लिए जितना संभव हो सके उतना करीब रहना पसंद करता हूं, जितना करीब हो सकता है जितना मैं अपने मस्तिष्क को चुनौती के लिए तैयार कर सकता हूं। जब संभव हो तो मैं एफ # का उपयोग करता हूं। आम तौर पर, मैं या तो VB.NET या C# (या VBA, जब मैं वास्तव में दुर्भाग्यपूर्ण हूं) के साथ अटक गया हूं। तो मेरी भाषाएं मुझे कार्यात्मक दृष्टिकोण से बहुत दूर भटकने की अनुमति देती हैं।एक कार्यात्मक प्रोग्रामिंग पैराडिग

ऐतिहासिक रूप से मैंने लॉगिंग और उपयोगकर्ता के साथ संवाद करने को अनदेखा कर दिया है जब तक कि मुझे नतीजा न हो - बस उपयोगकर्ता को प्रतीक्षा करें। अब मैं स्टेटस बार के लॉगिंग और/या अपडेट को लागू करने की कोशिश कर रहा हूं। यह आसान है, क्योंकि मेरी भाषाएं मुझे जब भी चाहें मानक आउटपुट लिखने की अनुमति देती हैं। लेकिन पूरी तरह से कार्यात्मक स्टैंड-प्वाइंट से, किसी व्यक्ति के बाहरी कार्य में क्या हो रहा है, इस बारे में जानकारी लीक करने के बारे में कोई कैसे जाता है? गणना के दौरान उपयोगकर्ता के साथ लॉगिंग या संचार कर रहा है बस पूरी तरह कार्यात्मक दृष्टिकोण के विपरीत?

मुझे यकीन है कि हास्केल में एक मोनाड का उपयोग करेगा। अन्य भाषाओं का उपयोग करते समय क्या?

धन्यवाद।

+0

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

+0

शायद यह अच्छी सलाह है ... –

उत्तर

8

चलो हास्केल के monadic समाधान पर एक नजर है

यह एक अधिक व्यावहारिक दृष्टिकोण है। लॉगिंग के पीछे विचार यह है कि हमारे कम्प्यूटेशंस में एक अतिरिक्त विधि होती है जो कहीं "आउट" संदेश लिखती है। कई मायनों में इस तरह के संगणना का प्रतिनिधित्व करने के लिए कैसे कर रहे हैं, लेकिन सबसे आम में से एक एक इकाई बनाने के लिए है:

class (Monad m) => MonadWriter w m | m -> w where 
    tell :: w -> m() 

प्रकार w संदेशों का प्रतिनिधित्व करता है और समारोह tell क्या एक monadic में "भेजता है" संदेश है (प्रभाव पूर्ण) गणना।

नोट्स:

  • हास्केल के MonadWriter वास्तव में अमीर है, यह काम करता है कि जांच करने और w संशोधित है, लेकिन अब के लिए है कि एक तरफ रख दें जाने के लिए अनुमति देते हैं।
  • | m -> w भाग स्पष्टीकरण के लिए वास्तव में महत्वपूर्ण नहीं है, इसका मतलब है कि w किसी दिए गए m के लिए तय किया गया है।

सबसे अधिक उपयोग किया जाने वाला कार्यान्वयन Writer है, जो मूल रूप से केवल एक जोड़ी है।इसका एक तत्व गणना का परिणाम है और दूसरा तत्व लिखित संदेशों का अनुक्रम है। (वास्तव में यह वास्तव में एक अनुक्रम नहीं है, यह अधिक सामान्य है - एक मोनोइड, जो एक से अधिक संदेशों को एक साथ जोड़ने के लिए संचालन को परिभाषित करता है।) आप Writer module को देखकर हास्केल के समाधान की जांच कर सकते हैं। हालांकि यह WriterT मोनैड ट्रांसफॉर्मर का उपयोग करके अधिक सामान्य रूप से लिखा गया है, इसलिए यदि आप एक मोनड प्रशंसक नहीं हैं, तो इसे पढ़ने में काफी मुश्किल हो सकती है। वही बात अन्य कार्यात्मक भाषाओं में भी की जा सकती है, उदाहरण के लिए this example in Scala देखें।

लेकिन उपरोक्त प्रकार की कक्षा के अन्य संभावित, अधिक दुष्प्रभाव उन्मुख (अभी भी कार्यात्मक) कार्यान्वयन हैं।

{-# LANGUAGE FunctionalDependencies, TypeSynonymInstances, FlexibleInstances #-} 

instance MonadWriter String IO where 
    tell = putStrLn 

यहाँ हम कहते हैं कि IO एक लॉगिंग सुविधा कि stdout में String रों लिखते हैं के रूप में इस्तेमाल किया जा सकता है: हम, कुछ बाहर सिंक करने के लिए संदेश फेंकना stdout के लिए की तरह, आदि उदाहरण के लिए tell परिभाषित कर सकते हैं एक फाइल करने के लिए, । (यह सिर्फ एक सरल उदाहरण है, एक पूर्ण कार्यान्वयन शायद एक इकाई ट्रांसफार्मर है कि किसी भी IO आधारित इकाई को tell कार्यक्षमता जोड़ना होगा होगा।)

+0

कक्षाएं और वस्तुओं? Whaaaat? यह कार्यात्मक प्रोग्रामिंग प्रतिमान नहीं है, यह केवल एफओपी में ओओपी है। –

+4

मुझे बिंदु नहीं दिख रहा है, हास्केल में कक्षाएं टाइप करें ओओ कक्षाओं से काफी अलग हैं। –

+0

धन्यवाद। हो सकता है कि मैं भी बिंदु नहीं देख सकता। इस जवाब में, कक्षा का कोई उपयोग केस नहीं है। कृपया, लाइब्रेरी के बजाय लॉगिंग उपयोग के क्लाइंट पक्ष पर ध्यान केंद्रित करें। धन्यवाद! –

3

मैं कार्यात्मक प्रोग्रामिंग करने के लिए नया हूँ, लेकिन यहाँ स्काला में एक प्रयास है:

object FunctionalLogging { 

    type Result = Int 

    class ResultWithLogging(val log: List[String], val result: Result) {} 

    def functionWithLogging(log: List[String], arg: String): ResultWithLogging = { 
    def function(arg: String): Result = arg.length 

    new ResultWithLogging(log :+ ("Calling function(" + arg +")"), function(arg)) 
    } 

    val result = functionWithLogging(List(), "Hello world!") 

    // -- Pure functional code ends here -- 
    println("Result = " + result.result) 
    println("Log = " + result.log) 
} 

ऐसा नहीं है कि में कार्यात्मक कोई साइड इफेक्ट नहीं है, लेकिन स्पष्ट रूप से लॉग समारोह तर्क और बदले का हिस्सा है, इसलिए यह बहुत ही सुरुचिपूर्ण या व्यावहारिक नहीं है।

ऐसा लगता है कि लॉगिंग परिभाषा के अनुसार एक वांछनीय दुष्प्रभाव है, इसलिए यदि आप मेरी परिभाषा के साथ जाते हैं तो प्रश्न यह है कि कार्यात्मक कोड से गैर-कार्यात्मक को अलग कैसे किया जाए। प्रैक्टिस में मैं शायद स्काला ऑब्जेक्ट (संभवतः एक सिंगलटन की तरह बहुत अधिक - एक विशेषता शायद बेहतर स्कैला) से शुरू करूंगा, या एक अभिनेता लॉगिंग संदेशों को जमा करने के लिए और जो कुछ भी उनके साथ किया जाना चाहिए। Logging in Scala

संपादित

यह सवाल हास्केल monads और आईओ के बारे में वार्ता: What other ways can state be handled in a pure functional language besides with Monads?

+0

मुझे आपकी विचार प्रक्रिया पसंद है। मेरे मामले में, हालांकि, फ़ंक्शन लंबे समय से चल रहा था, और मैं इसकी लॉग रिपोर्ट करने की वापसी के इंतजार के बजाय, प्रक्रिया के रूप में रिपोर्ट करना चाहता था। फिर भी, अगर कोई और मेरे प्रश्न का उत्तर नहीं देता है, तो शायद मैं इसे उत्तर के रूप में चिह्नित करूंगा, क्योंकि, हास्केल का जवाब एक महान है, मेरा प्रश्न गैर-मोनाद दृष्टिकोणों के बारे में अधिक विशेष रूप से था। धन्यवाद! –