2015-10-20 8 views
7

मुझे आश्चर्य है कि null के लिए समकक्ष या मोनैड के लिए सामान्यीकृत सूचियों से कुछ है या नहीं। फिलहाल मैं == mzero के साथ गलत मूल्य खोजने की कोशिश कर रहा हूं। लेकिन mzero /= Left "foo" लागू होने के बाद इस तरह की जांच झूठी सकारात्मक साबित करती है।हास्केल जांचें कि क्या मोनैड में कोई मान मौजूद है

क्या मानक पुस्तकालयों में जो कुछ मैं चाहता हूं उसे व्यक्त करने का एक शानदार तरीका है?

+0

ऐसा लगता है कि आपके प्रश्न कुछ – Zeta

+0

@Zeta हां में बाधित हो गए हैं, मैंने गलती से अपने कीबोर्ड पर रिटर्न कुंजी मारा। ^^ – bash0r

+1

मुझे लगता है कि सभी मोनैड के लिए "गलत मूल्य" (मुझे लगता है कि आपको किसी प्रकार की त्रुटि/खाली स्थिति) के रूप में देखा गया है, इसके साथ कुछ समस्याएं हो सकती हैं - क्या आप कुछ परिभाषा/कानूनों के साथ आ सकते हैं जो अलग हैं 'मोनाडप्लस' के लोग? – Carsten

उत्तर

12

धारणा Monad typeclass द्वारा कब्जा कर लिया नहीं है "कोई मान"। आखिरकार, Monad केवल आपको अनुक्रम (>>=) क्रियाओं के लिए कुछ देता है (पिछले परिणाम को बांधें)। और MonadPlus आपको mzero के साथ गणना "शॉर्टकट" करने का एक तरीका देता है (कानूनों और mplus पर एक नज़र डालें)।

हालांकि, एक या कई मूल्यों को रखने में सक्षम होने के कारण आम तौर पर उन सभी मूल्यों को एक साथ जोड़कर सक्षम किया जाता है। और वास्तव में, Data.Foldable एक समारोह सुविधा भी null कहा जाता है:

> import qualified Data.Foldable as F 
> 
> showAndTell :: (Show (t a), Foldable t) => t a -> IO() 
> showAndTell k = 
> putStrLn $ " F.null (" ++ show k ++ ") is " ++ show (F.null k) 

> main = do 
> putStrLn "Using F.null on 'empty' things:" 
> showAndTell $ (Left "Error" :: Either String Int) 
> showAndTell $ (Nothing :: Maybe Integer) 
> showAndTell $ ([]  :: [Double]) 
> 
> putStrLn "" 
> putStrLn "Using F.null on 'filled' things:" 
> showAndTell $ (Right 123 :: Either String Integer) 
> showAndTell $ (Just 123 :: Maybe Integer) 
> showAndTell $ ([1,2,3] :: [Int]) 

परिणाम:

Using F.null on 'empty' things: 
    F.null (Left "Error") is True 
    F.null (Nothing) is True 
    F.null ([]) is True 

Using F.null on 'filled' things: 
    F.null (Right 123) is False 
    F.null (Just 123) is False 
    F.null ([1,2,3]) is False 

तो तुम क्या खोज रहे हैं Foldable का हिस्सा है, नहीं Monad है। यह केवल जीएचसी 7.10 या उच्चतर पर काम करेगा, क्योंकि Data.Foldable.null आधार 4.8.0.0 में पेश किया गया था। आप GHC के एक पुराने संस्करण के साथ फंस रहे हैं, तो आप इकाई के बाहर से

> isEmpty :: F.Foldable t => t a -> Bool 
> isEmpty = F.foldr (\_ _ -> False) True 
+0

मुझे डर है कि आपको पिछड़ा संगतता नहीं मिलती है, क्योंकि जीएचसी 7.10 तक 'शून्य' को 'फोल्डबल' के लिए सामान्यीकृत नहीं किया गया था। –

+0

@ ØrjanJohansen Whoops। मैंने नहीं देखा कि मैं अपने जीएचसी 7.10 पीसी पर था। – Zeta

+1

@Zeta चिंता न करें, मैं 7.10 का भी उपयोग कर रहा हूं। फोल्डबल टाइप क्लास को इंगित करने के लिए धन्यवाद। यही वही है जो मैं ढूंढ रहा हूं। :) – bash0r

5

मैं नहीं मौके पर ही किसी भी साधारण समारोह है कि सभी monads Maybe, Either e, MaybeT m और ExceptT e m है, जो मुख्य monads मुझे लगता है कि है "गलत मूल्यों" के बारे में सोच सकते हैं के लिए काम करता है याद कर सकते हैं।

चूंकि जीएचसी 7.10, null वास्तव में सामान्यीकृत किया गया है (Foldable पर), इसलिए यह पहले दो पर काम करता है।

पिछले तीन (Either e दोनों विधियों के साथ काम करता है) और उनके संस्करणों को परिवर्तित करने के लिए, आप शायद catchError फ़ंक्शन का उपयोग कर सकते हैं।

(पिछले दो है हालांकिFoldable उदाहरणों, उनके null गलत बात करता है।)

5

निश्चित रूप से नहीं कर सकते हैं। यदि आप nonEmpty :: MonadPlus m => m a -> Bool जैसे कुछ खोज रहे हैं तो यह असंभव है।

आपको यह पता लगाने के लिए वास्तव में monadic गणना चलाने की आवश्यकता होगी कि यह "खाली" है या नहीं। लेकिन मोनैड को चलाने के लिए किसी प्रकार के इनपुट की आवश्यकता हो सकती है (उदाहरण के लिए State या यहां तक ​​कि केवल Reader), और IO के चरम मामले में आप बाहर से मोनाड नहीं चला सकते हैं। अब वे उदाहरण MonadPlus अपने स्वयं के AFAICR पर नहीं हैं, लेकिन उन्हें विफलता के साथ बढ़ाएं (उदा। MaybeT) और अचानक उनके बारे में एक स्पष्ट परिभाषा है कि उनके लिए "खाली" होना क्या है, लेकिन वही प्रतिबंध अभी भी लागू होते हैं। चूंकि अज्ञात मोनड उनमें से एक हो सकता है, इसलिए आपको कोई जानकारी नहीं मिल सकती है।

एक संभावित हस्ताक्षर nonEmpty :: MonadPlus m => m a -> m Bool हो सकता है (हालांकि मुझे यकीन नहीं है कि इसमें एक समझदार कार्यान्वयन है)।लेकिन मुझे नहीं लगता कि आप यही कर रहे हैं, क्योंकि यह वास्तव में null को सामान्यीकृत नहीं करता है; आप सूचियों के लिए [False] या [True] सेवानिवृत्त हो जाएंगे (या संभवतः [True, True, True, ...] इनपुट के समान तत्वों के साथ भी), जो थोड़ा अजीब है।

मुझे लगता है कि मोनैड null के लिए गलत "सामान्यीकरण की धुरी" पर हैं; आप एक अमूर्त चाहते हैं जो Monad से कंटेनर को बेहतर ढंग से चित्रित करता है (बहुत सारे मोनैड कंटेनर हैं, लेकिन ऐसी कई अन्य चीजें हैं जो बहुत अलग हैं, इसलिए मनमाने ढंग से मोनैड्स पर काम करने वाला कोड कंटेनर जैसी गुणों को नहीं मान सकता है)। जीएचसी -710 में होने वाली Foladable को सामान्य बनाना एक बहुत अच्छी शर्त है। आप शायद CanBeEmpty टाइप क्लास बना सकते हैं जो Foldable से कुछ और चीजों को स्वीकार करता है; मुझे नहीं पता कि ऐसी चीज पहले से मौजूद है।

+0

'Foldable' पूरी तरह से पर्याप्त था। मुझे नहीं पता था कि शून्य को जीएचसी 7.10 के साथ सामान्यीकृत किया गया है और यदि मैं एक प्रकार की कक्षा है तो पर्याप्त रूप से 'फोल्डबल' जैसी कुछ लागू नहीं करना चाहता था। – bash0r

2

मूर्खतापूर्ण चीज शून्य को पहचानने का प्रयास नहीं करना है, बल्कि शून्य के मामले में इच्छित व्यवहार प्रदान करना है।

यह mplus या समकक्ष (हालिया प्रस्तुतियों में) <|> करता है; यह इस मामले में चलाने के लिए एक कार्रवाई श्रृंखला है कि पहली कार्रवाई विफल हो जाती है। यह उन मोनैड्स पर catchError जैसा है जो catchError समर्थन करता है। यह शैल या पर्ल प्रोग्रामिंग foo || bar में सामान्य मुहावरे के समान है जिसका अर्थ है foo और फिर foo विफल होने पर रन बार।

सूची मोनैड में सावधान रहें कि यह सभी विकल्पों को चलाएगा क्योंकि इस प्रकार सूची मोनैड को 'एकाधिक संभावनाओं' मॉडलिंग के लिए डिजाइन करने के लिए डिज़ाइन किया गया है।

मैं अक्सर MaybeT या EitherT पर <|> का उपयोग मॉडल करने के लिए छोड़ दिया पक्षपाती विकल्प है, अर्थात "जब तक एक सफल होता है बदले में इन विकल्पों के सभी प्रयास करें"।

सावधान रहें कि <|>EitherT के लिए त्रुटि संदेश को छोड़ दें (क्योंकि यह एक सफल गणना में विफल गणना करता है); अगर आप त्रुटि संदेश को सहेजना चाहते हैं और किसी भी तरह से इसे संसाधित करना चाहते हैं, तो फिर, catchError आप चाहते थे।

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