मैं ऐसा करने की कोशिश कर रहा हूं जो हास्केल में अंधेरे से स्पष्ट होना चाहिए, जो Just [1]
और Just [2]
से Just [1, 2]
पर जा रहा है। हालांकि मुझे कुछ भी ऑनलाइन नहीं मिल रहा है क्योंकि मैं संबंधित लेकिन अनुपयोगी पृष्ठों को ढूंढता रहता हूं। तो, आप इसे कैसे प्राप्त करते हैं?हास्केल में विलय/संलग्न जस्ट्स
उत्तर
आप liftA2 (++)
उपयोग कर सकते हैं:
liftA2 (++) :: Maybe [a] -> Maybe [a] -> Maybe [a]
liftA2
सिर्फ एक Applicative
में एक द्विआधारी समारोह लिफ्टों। Applicative
एस को संदर्भ में मनमाने ढंग से तर्कों के कार्यों को उठाने के लिए डिज़ाइन किया गया था, इसलिए वे इसके लिए बिल्कुल सही हैं। इस मामले में, Applicative
हम उपयोग कर रहे हैं Maybe
है। यह कैसे काम करता देखने के लिए, हम परिभाषा देख सकते हैं: (a -> b) -> f a -> f b
:
liftA2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c
liftA2 f a b = f <$> a <*> b
(<$>)
सिर्फ f
अंदर एक ऑपरेटिंग को शुद्ध मूल्यों पर किसी भी समारोह लिफ्टों। (यह सिर्फ fmap
के लिए एक उपनाम है, यदि आप Functor
रों से परिचित हैं।) Maybe
के लिए:
_ <$> Nothing = Nothing
f <$> Just x = Just (f x)
(<*>)
थोड़ा जटिल काम है: यह f
अंदर एक मूल्य के f
अंदर एक समारोह लागू होता है: f (a -> b) -> f a -> f b
। Maybe
के लिए:
Just f <*> Just x = Just (f x)
_ <*> _ = Nothing
तो, (वास्तव में, f <$> x
जो Maybe
के लिए Just f <*> x
है pure f <*> x
के रूप में एक ही बात है।) हम liftA2 (++)
की परिभाषा का विस्तार कर सकते हैं:
liftA2 (++) a b = (++) <$> a <*> b
-- expand (<$>)
liftA2 (++) (Just xs) b = Just (xs ++) <*> b
liftA2 (++) _ _ = Nothing
-- expand (<*>)
liftA2 (++) (Just xs) (Just ys) = Just (xs ++ ys)
liftA2 (++) _ _ = Nothing
दरअसल, हम इन ऑपरेटरों का उपयोग किसी भी किसी भी Applicative
में तर्कों की संख्या को उठाने के लिए कर सकते हैं, j liftA2
के पैटर्न का पालन करके ust। इसे आवेदक शैली कहा जाता है, और यह idiomatic Haskell कोड में बहुत आम है। a
और b
पहले से ही चर हैं, तो इस मामले में, यह सीधे (++) <$> a <*> b
लिखकर इसका उपयोग करने के लिए और अधिक मूर्खतापूर्ण हो सकता है। (दूसरी ओर, यदि आप आंशिक रूप से यह लागू कर रहे हैं - एक उच्च क्रम कार्य करने के लिए इसे पारित करने के कहते हैं, - तो liftA2 (++)
बेहतर है।)
हर Monad
एक Applicative
है, इसलिए यदि आप कभी अपने आप से खोजने की कोशिश एक संदर्भ में एक समारोह "लिफ्ट", Applicative
शायद आप जो खोज रहे हैं।
जबकि @ ehird का जवाब बहुत अच्छा है, मैं रूप में एक noobish समाधान का इस्तेमाल किया है जाएगा:
mergeJust a b = do
a' <- a
b' <- b
return (a' ++ b')
+1 सरल उपकरण से लैस भी नोबस, इस समस्या को हल कर सकते हैं। आप एक मोनद समझ के रूप में भी लिख सकते हैं: '[ए' ++ बी '| एक '<- ए, बी' <- बी] ' –
Just
रों की एक सूची का हल का विस्तार करने के लिए, आप इस्तेमाल कर सकते हैं
fmap join $ sequence [Just[1],Just[2],Just[3]]
-- Just [1,2,3]
चूंकि इसका अन्य समाधानों में उल्लेख नहीं किया गया था, इसलिए मैं इसे यहां कहूंगा। अपने काम को पूरा करने का सबसे आसान तरीका, मेरी राय में, Data.Monoid
से <>
(या mappend
) का उपयोग करना है।
import Data.Monoid
Just [1,2] <> Just [7,8] == Just [1,2,7,8]
हालांकि, ध्यान दें कि यह समाधान, ehird के अनुप्रयोगी समाधान के विपरीत, Nothing
मूल्यों पर शॉर्ट सर्किट होगा।
Just [1,2] <> Nothing ---> Just [1,2]
--However
(++) <$> Just [1,2] <*> Nothing ---> Nothing
कभी-कभी यह उचित व्यवहार होगा, कभी-कभी नहीं। –
बहुत बढ़िया :) धन्यवाद, आपने मुझे अपने बालों को फाड़ने से बचा लिया है। मान लीजिए कि आप '[2]' और 'बस [3] '->' बस [2, 3] 'के बराबर जानते हैं? :) –
@DeanBarnes: '(2 :) <$> बस [3]' –
शानदार जवाब, धन्यवाद @ehird! यह मूल रूप से अब से मेरा संदर्भ है :) –