2012-01-18 9 views
7

एक मोनाद पर सख्ती से कैसे फोल्ड करता है? Data.Foldable सख्त foldl' और monadic foldlM है, लेकिन कोई सख्त foldlM' नहीं है? क्या मोनाद द्वारा किसी भी तरह से सख्तता को परिभाषित किया गया है? यदि हां, तो यह कैसे काम करता है?क्या हैस्केल में foldlM है?

कल्पना कीजिए कि मुझे यह निर्धारित करना होगा कि अंगूठी तत्वों की एक विशाल सूची का उत्पाद शून्य है, लेकिन मेरी अंगूठी एक अभिन्न डोमेन नहीं है, यानी इसमें शून्य devisors शामिल हैं। इस मामले में, मुझे सूची में foldl मेरी गुणा *** सूची में फिर से चित्रित करना चाहिए, लेकिन पूर्ण उत्पाद पर प्रतीक्षा करने के बजाए उत्पाद शून्य होने पर False लौटाएं।

safelist :: [p] -> Bool 
safelist [] = True 
safelist (x:xs) = snd $ foldl' f (x,True) xs 
    where f (u,b) v = (w, b && w /= Zero) where w = u *** v 

मैं शायद थोड़ा Maybe इकाई के foldlM का उपयोग कर, लेकिन ऐसा करने के लिए इस कोड को आसान बनाने में कर सकता है प्रतीत होता है की आवश्यकता कठोरता का अभाव है।

उत्तर

8

ऐसी कोई मानक समारोह नहीं है, लेकिन इसे परिभाषित करना आसान है:

foldM' :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a 
foldM' _ z [] = return z 
foldM' f z (x:xs) = do 
    z' <- f z x 
    z' `seq` foldM' f z' xs 

यह सिर्फ मानक foldM है, लेकिन यह में ing ही seq साथ है कि foldl' (foldl की तुलना में)। यह शायद कहीं भी मानक परिभाषित नहीं किया गया है क्योंकि यह सभी उपयोगी होने की संभावना नहीं है: अधिकांश मोनैड के लिए, (>>=) इस अर्थ में "सख्त" है कि आपको स्टैक को बहने के बिना बाएं गुना का उपयोग करने की आवश्यकता है; यह केवल तभी उपयोगी होता है जब आपके अत्यधिक भाग वापस लौटे मूल्यों में होते हैं, लेकिन foldM का एक उपयोगी अनुप्रयोग अंतिम चरण से मूल्य के साथ कुछ monadic गणना करेगा, जिससे यह असंभव हो जाएगा।

मुझे लगता है कि आपका कोड उतना आसान है जितना है; मुझे संदेह है कि foldM' इसे और अधिक सुरुचिपूर्ण बना देगा।

+0

आह, मुझे लगता है कि मोनड चीजों को सख्त बना सकता है अगर इसमें सख्त झंडे हों, लेकिन अन्यथा नहीं। और कोई मानक monads ऐसा करते हैं। धन्यवाद! –

+3

@ जेफबर्जेस - यहां एक विज्ञापन-प्रकार का अवलोकन है जिसमें मोनाडिक '>> =' सख्त बनाम आलसी हैं: http://stackoverflow.com/a/8250334/208257 –

+0

दरअसल, मुझे संदेह है कि 'foldM' मदद करेगा अगर आपका '(>> =)' बहुत आलसी है, उदाहरण के लिए आलसी 'राज्य' मोनैड द्वारा लौटाए गए मूल्य को मजबूर करना जरूरी नहीं है कि वह राज्य को मजबूर करे। – ehird

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