मैं एक नंबर जोड़कर जब तक मैं एक ऐसा नाम है जो अभी तक नहीं है पाया द्वारा एक निर्देशिका का नाम खोजने की कोशिश कर रहा था के साथ filterM का उपयोग कैसे करें मौजूद हैं:एक अनंत सूची
head <$> filterM (fmap not . fexists_) [ getDatedDir t d n | n <- [0..] ]
इस के साथ समस्या यह है कि कभी नहीं है रिटर्न। मुझे लगता है कि समस्या यह है कि हालांकि आईओ एक फंक्टर है, फिल्टरएम को सिर प्रभाव से पहले सभी आईओ करना है; यानी, यह प्रत्येक एन के लिए fexists का मूल्यांकन करना है - और यह निश्चित रूप से अनंत है।
अब, मैं इस का समाधान कर सकते हैं:
go t d 0
where go t d n = do
let dir = getDatedDir t d n
fexists_ dir >>= \case
False -> return dir
True -> go t d (n+1)
लेकिन मुझे लगता है कि वहाँ एक और अधिक सुरुचिपूर्ण दृष्टिकोण होने के लिए filterM या कुछ इसी तरह का उपयोग कर चाहिए।
यह एक सामान्य पर्याप्त पैटर्न की तरह लगता है कि शायद नियंत्रण में एक मौजूदा कार्य है। मोनाड, मैं इसे देख नहीं रहा हूं।
आप 'होट' आईओ 'कार्यों की अनंत सूची को ध्वस्त करने के लिए' asum' का उपयोग कर सकते हैं और इस उत्तर में थोड़ा सा सफल होने वाला पहला प्राप्त कर सकते हैं: https://stackoverflow.com/questions/47120384/keeping- io-lazy-under-append/47126169 # 47126169 – danidiaz
आलस्य और आईओ कभी-कभी अच्छी तरह से मिश्रण नहीं करते हैं। आप अपने आईओ ऑपरेशंस को आलसी में बदलने के लिए [System.IO.Lazy] (https://hackage.haskell.org/package/lazyio-0.1.0.4/docs/System-IO-Lazy.html) देख सकते हैं। – Redu