जबकि विल्म वान ऑनसेम और ऑर्गाज़ॉयड के दोनों जवाब अच्छे हैं (ऊपर की ओर), आप समस्या के हिस्से को अधिक सामान्यीकृत तरीके से भी संपर्क कर सकते हैं, न केवल सूचियों के लिए।
निम्नलिखित के लिए, आप इन आयात की जरूरत के लिए जा रहे:
import Control.Monad (MonadPlus, mfilter)
import Data.Maybe (fromMaybe, listToMaybe)
मैं सवाल समझ रहा हूँ सही ढंग से, आप में से as
, bs
, और cs
सभी संयोजनों की कोशिश करना चाहते हैं। आप आमतौर पर Applicative
typeclass के साथ संयोजन की तरह व्यवहार को प्राप्त कर सकते हैं:
combinations = (,,) <$> as <*> bs <*> cs
(,,)
एक समारोह है कि तीन अलग-अलग मूल्यों से ट्रिपल (तीन तत्व tuples) बनाता है।
इस सूची के लिए काम करता है, क्योंकि सूचियों अनुप्रयोगी हैं:
*Prelude> (,,) <$> [1,2] <*> ["foo", "bar"] <*> [True, False]
[(1,"foo",True),(1,"foo",False),(1,"bar",True),(1,"bar",False),(2,"foo",True),(2,"foo",False),(2,"bar",True),(2,"bar",False)]
लेकिन यह भी जैसे के लिए काम करता Maybe
रों:
try' :: MonadPlus m => ((a, a, a) -> Bool) -> m a -> m a -> m a -> m [a]
try' predicate as bs cs =
tripleToList <$> mfilter predicate combinations
where
combinations = (,,) <$> as <*> bs <*> cs
tripleToList (a, b, c) = [a, b, c]
आप इस सहायक समारोह पूरी तरह से सामान्य है कि ध्यान देंगे:
*Prelude> (,,) <$> Just 1 <*> Just "foo" <*> Just False
Just (1,"foo",False)
इसी के साथ
, अब आप अपने समारोह के मुख्य परिभाषित कर सकते हैं। यह किसी भी MonadPlus
किसी भी निहित तत्व a
के उदाहरण के लिए काम करता है।
यहाँ कुछ उदाहरण हैं:
*Answer> try' (const True) ["foo", "bar", "baz"] ["qux", "quux", "quuz", "corge"] ["grault", "garply"]
[["foo","qux","grault"],["foo","qux","garply"],["foo","quux","grault"],["foo","quux","garply"],["foo","quuz","grault"],["foo","quuz","garply"],["foo","corge","grault"],["foo","corge","garply"],["bar","qux","grault"],["bar","qux","garply"],["bar","quux","grault"],["bar","quux","garply"],["bar","quuz","grault"],["bar","quuz","garply"],["bar","corge","grault"],["bar","corge","garply"],["baz","qux","grault"],["baz","qux","garply"],["baz","quux","grault"],["baz","quux","garply"],["baz","quuz","grault"],["baz","quuz","garply"],["baz","corge","grault"],["baz","corge","garply"]]
*Answer> try' (const False) ["foo", "bar", "baz"] ["qux", "quux", "quuz", "corge"] ["grault", "garply"]
[]
*Answer> try' (const True) (Just "foo") (Just "bar") (Just "baz")
Just ["foo","bar","baz"]
*Answer> try' (const False) (Just "foo") (Just "bar") (Just "baz")
Nothing
आपने ध्यान दिया जाना चाहिए कि अगर predicate
हमेशा False
देता है, तुम वापस कुछ भी नहीं मिलेगा।सूचियों के लिए, आपको खाली सूची मिलती है; Maybe
के लिए, आपको सचमुच Nothing
मिलते हैं।
अभी तक यह सभी सामान्य है, लेकिन checkIfCorrect
नहीं है। ऐसा लगता है कि आप मिलान करने वाले पहले तत्व प्राप्त करना चाहते हैं। आपको लगता है कि प्राप्त कर सकते हैं checkIfCorrect
साथ try'
रचना द्वारा: यहाँ
try :: [String] -> [String] -> [String] -> [String]
try as bs cs = fromMaybe [] $ listToMaybe $ try' isCorrect as bs cs
where isCorrect (a, b, c) = checkIfCorrect a b c
, मैं आदेश checkIfCorrect
समारोह uncurry करने के लिए एक निजी isCorrect
समारोह बना लिया है। इसके बाद मैंने परिणामी सूची के पहले तत्व को वापस करने के लिए listToMaybe
और fromMaybe
का संयोजन उपयोग किया है। अन्य उत्तर यहां head
का उपयोग करते हैं, लेकिन यदि सूची खाली है तो यह अपवाद फेंकने जा रहा है, इसलिए मैंने इसके बजाय इस संयोजन का उपयोग किया, क्योंकि यह सुरक्षित है।
आप 'try' को बदलना चाहते हैं ताकि वापसी प्रकार सूची के बजाय 3 मानों का एक टुपल हो। इस तरह यह स्पष्ट है कि आप सूची में बिल्कुल 3 मान होने की उम्मीद करते हैं। – 4castle