दिलचस्प पोस्ट
तोड़ जब अपवाद फेंक दिया जाता है जावा में उम्मीद के रूप में यह regex काम क्यों नहीं करता है? gprolog: अपवाद के बाद एक स्टैकट्र्रेस प्राप्त करना कैसे एक विधि संदर्भ विधेयक को नकारना पायथन में स्ट्रिंग को विभाजित और पार्स कैसे कर सकता हूं? आच्छादित पृष्ठभूमि क्षेत्र की चमक के आधार पर पाठ रंग बदलें? जावा में फ़ाइल संचालन को स्थानांतरित / कॉपी करें नोड- http-proxy के साथ vhosts का उपयोग कैसे करें? मैं एक एसक्यूएल को तैयार स्थिति में कैसे प्राप्त करूं? एक एंड्रॉइड SQLite डेटाबेस में एक तालिका मौजूद है या नहीं, यह कैसे पता चलता है? मार्स के नुकसान (एकाधिक सक्रिय परिणाम समूह)? आईफोन के ऑनस्क्रीन कीबोर्ड की ऊंचाई क्या है? जावा में दस्तावेज़ नोड को स्ट्रिंग एक्सएमएल टुकड़ा कन्वर्ट PHP: क्या mysql_real_escape_string उपयोगकर्ता इनपुट को साफ करने के लिए पर्याप्त है? सिथन के साथ सी कोड का सरल लपेटन

हस्केल में 2 सूचियों का कार्टेशियन उत्पाद

मैं हास्केल में 2 सूचियों के कार्टेशियन उत्पाद का उत्पादन करना चाहता हूं, लेकिन मैं यह कैसे काम करना नहीं कर सकता। कार्टेशियन उत्पाद सूची के सभी तत्वों को जोड़ता है:

xs = [1,2,3] ys = [4,5,6] cartProd :: [a] -> [b] -> [(a,b)] cartProd xs ys ==> [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)] 

यह एक वास्तविक होमवर्क प्रश्न नहीं है और यह किसी भी प्रश्न से संबंधित नहीं है, लेकिन जिस समस्या से इस समस्या का समाधान हो रहा है, उसके साथ मैं एक के साथ मदद कर सकता हूँ।

Solutions Collecting From Web of "हस्केल में 2 सूचियों का कार्टेशियन उत्पाद"

यह सूची की समझ के साथ बहुत आसान है। xs और ys सूचियों के कार्टेसियन उत्पाद प्राप्त करने के लिए, हमें बस प्रत्येक xs में x तत्वों के लिए ट्यूपल (x,y) लेना होगा और प्रत्येक तत्व y में होगा।

यह हमें निम्न सूची समझ देता है:

 cartProd xs ys = [(x,y) | x <- xs, y <- ys] 

जैसा कि अन्य उत्तरों ने नोट किया है, सूची की समझ का उपयोग करना हास्केल में ऐसा करने का सबसे स्वाभाविक तरीका है।

यदि आप हास्केल सीख रहे हैं और Monad जैसी प्रकार के वर्गों के बारे में Monad विकास पर काम करना चाहते हैं, हालांकि, यह पता लगाना एक मजेदार अभ्यास है कि यह थोड़ा कम परिभाषा क्यों समतुल्य है:

 import Control.Monad (liftM2) cartProd :: [a] -> [b] -> [(a, b)] cartProd = liftM2 (,) 

आप शायद यह कभी वास्तविक कोड में नहीं लिखना चाहते हैं, लेकिन बुनियादी विचार कुछ ऐसा है जिसे आप हास्केल में हर समय देखेंगे: हम एक मोनाद-इन में गैर-मोनैडाइक फ़ंक्शन (,) को उठाने के लिए लिफ्ट liftM2 का उपयोग कर रहे हैं यह मामला विशेष रूप से सूची मोनद

यदि यह कोई मतलब नहीं है या उपयोगी नहीं है, तो इसे भूल जाओ- समस्या को देखने का यह एक और तरीका है।

यदि आपकी इनपुट सूचियां एक ही प्रकार के हैं, तो आप sequence ( List मोनद का उपयोग करके) का उपयोग करते हुए सूचियों की एक मनमानी संख्या के कार्टेसियन उत्पाद प्राप्त कर सकते हैं। इससे आपको ट्यूप्ले की सूची के बजाय सूचियों की एक सूची मिल जाएगी:

 > sequence [[1,2,3],[4,5,6]] [[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]] 

कार्यात्मक फ़ंक्टर्स के साथ ऐसा करने का एक बहुत ही शानदार तरीका है:

 import Control.Applicative (,) <$> [1,2,3] <*> [4,5,6] -- [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)] 

बुनियादी विचार "लिपटे" तर्कों पर एक समारोह को लागू करना है, उदा

 (+) <$> (Just 4) <*> (Just 10) -- Just 14 

सूचियों के मामले में, समारोह सभी संयोजनों पर लागू किया जाएगा, इसलिए आपको जो करना है उसे (,) साथ "ट्यूपल" करना है

देखें http://learnyouahaskell.com/functors-applicative-functors-and-monoids#upplicative-functors या (अधिक सैद्धांतिक) http://www.soi.city.ac.uk/~ross/papers/Applicative.pdf के लिए विवरण।

सही तरीके से सूची की समझ का उपयोग किया जा रहा है, क्योंकि अन्य लोगों ने पहले से ही बताया है, लेकिन अगर आप किसी भी कारण के लिए सूची की समझ के बिना यह करना चाहते हैं, तो आप यह कर सकते हैं:

 cartProd :: [a] -> [b] -> [(a,b)] cartProd xs [] = [] cartProd [] ys = [] cartProd (x:xs) ys = map (\y -> (x,y)) ys ++ cartProd xs ys 

फिर भी यह पूरा करने का एक अन्य तरीका अनुप्रयोगों का उपयोग कर रहा है:

 import Control.Applicative cartProd :: [a] -> [b] -> [(a,b)] cartProd xs ys = (,) <$> xs <*> ys 

फिर भी एक और तरीका, नोटेशन का उपयोग कर:

 cartProd :: [a] -> [b] -> [(a,b)] cartProd xs ys = do x <- xs y <- ys return (x,y) 

खैर, यह करने के लिए एक बहुत आसान तरीका सूची की समझ के साथ होगा:

 cartProd :: [a] -> [b] -> [(a, b)] cartProd xs ys = [(x, y) | x <- xs, y <- ys] 

जो मुझे लगता है कि मैं यह कैसे करूँगा, हालांकि मैं किसी हास्केल विशेषज्ञ (किसी भी तरह से) नहीं हूँ

कुछ इस तरह:

 cartProd xy = [(a,b) | a <- x, b <- y] 

अन्य जवाब यह मानते हैं कि दो इनपुट सूची परिमित हैं। अक्सर, मुहावरेदार हास्केल कोड में अनंत सूची शामिल होती है, और इसलिए यह आवश्यक है कि एक अनंत कार्टेशियन उत्पाद को कैसे तैयार किया जाए, जिस पर जरूरी हो।

मानक दृष्टिकोण विकर्णकरण का उपयोग करना है; शीर्ष के साथ एक इनपुट और बाईं ओर अन्य इनपुट लिखना, हम एक दो-आयामी तालिका लिख ​​सकते हैं जिसमें इस तरह पूर्ण कार्टेशियन उत्पाद शामिल होता है:

  1 2 3 4 ... a a1 a2 a3 a4 ... b b1 b2 b3 b4 ... c c1 c2 c3 c4 ... d d1 d2 d3 d4 ... . . . . . . . . . . . . . . . . . . 

बेशक, किसी एक पंक्ति में काम करने से हमें अगली पंक्ति तक पहुंचने से पहले असीम तत्व मिलेगा; इसी प्रकार कॉलम-वार जा रहे हैं विनाशकारी। लेकिन हम किनारों के साथ जा सकते हैं जो नीचे और बाईं ओर जाते हैं, फिर से ग्रिड के किनारे तक पहुंचते समय हर बार दाहिनी ओर फिर से शुरू होते हैं।

 a1 a2 b1 a3 b2 c1 a4 b3 c2 d1 

…और इसी तरह। क्रम में, यह हमें देगा:

 a1 a2 b1 a3 b2 c1 a4 b3 c2 d1 ... 

इसे हास्केल में कोड करने के लिए, हम पहले संस्करण लिख सकते हैं जो दो-आयामी तालिका का उत्पादन करता है:

 cartesian2d :: [a] -> [b] -> [[(a, b)]] cartesian2d as bs = [[(a, b) | a <- as] | b <- bs] 

विकर्णकरण की एक अक्षम विधि, फिर विकर्णों के साथ पहली बार फिर से चलना है और फिर प्रत्येक विकर्ण की गहराई के साथ, हर बार उपयुक्त तत्व खींचकर। स्पष्टीकरण की सादगी के लिए, मैं मानूंगा कि दोनों इनपुट सूचियां अनंत हैं, इसलिए हमें सीमा जांच के साथ घूमने की ज़रूरत नहीं है

 diagonalBad :: [[a]] -> [a] diagonalBad xs = [ xs !! row !! col | diagonal <- [0..] , depth <- [0..diagonal] , let row = depth col = diagonal - depth ] 

यह कार्यान्वयन थोड़ा दुर्भाग्यपूर्ण है: दोहराई गई सूची अनुक्रमण प्रक्रिया !! हम जाने के रूप में अधिक से अधिक महंगा हो जाता है, काफी खराब असिम्पटिक प्रदर्शन दे रहा है एक अधिक कुशल कार्यान्वयन उपरोक्त विचार लेगा, लेकिन इसे ज़िप्पर के जरिये लागू कर देगा। तो, हम अपने अनंत ग्रिड को इस तरह तीन आकारों में विभाजित करेंगे:

 a1 a2 / a3 a4 ... / / b1 / b2 b3 b4 ... / / / c1 c2 c3 c4 ... --------------------------------- d1 d2 d3 d4 ... . . . . . . . . . . . . . . . 

शीर्ष बायां त्रिकोण हम पहले से उत्सर्जित किए गए बिट्स होंगे; शीर्ष दाहिनी चतुर्भुज में पंक्तियों को आंशिक रूप से उत्सर्जित किया जाएगा, लेकिन फिर भी परिणाम में योगदान होगा; और नीचे आयत पंक्तियाँ हैं जो हमने अभी तक उत्सर्जन शुरू नहीं की हैं। के साथ शुरू करने के लिए, ऊपरी त्रिकोण और ऊपरी चतुर्भुज खाली होगा, और नीचे आयत पूरे ग्रिड होगा। प्रत्येक चरण पर, हम ऊपरी चतुर्भुज में प्रत्येक पंक्ति के पहले तत्व को छोड़ सकते हैं (अनिवार्य रूप से तिरछी रेखा को एक से अधिक चलती है), फिर नीचे की आयत से ऊपरी चतुर्भुज में एक नई पंक्ति जोड़ें (अनिवार्य रूप से क्षैतिज रेखा नीचे एक )।

 diagonal :: [[a]] -> [a] diagonal = go [] where go upper lower = [h | h:_ <- upper] ++ case lower of [] -> concat (transpose upper') row:lower' -> go (row:upper') lower' where upper' = [t | _:t <- upper] 

हालांकि यह थोड़ा अधिक जटिल दिखता है, लेकिन यह काफी अधिक कुशल है। यह सीमा की जांच भी करता है कि हमने सरल संस्करण में दंडित किया था।

लेकिन आपको यह सब कोड खुद नहीं लिखना चाहिए, ज़ाहिर है! इसके बजाय, आप ब्रह्मांड पैकेज का उपयोग करना चाहिए Data.Universe.Helpers , (+*+) , जो केवल कार्टेशियन उत्पाद संचालन देने के लिए उपरोक्त cartesian2d और diagonal फ़ंक्शन को एकत्र करता है:

 Data.Universe.Helpers> "abcd" +*+ [1..4] [('a',1),('a',2),('b',1),('a',3),('b',2),('c',1),('a',4),('b',3),('c',2),('d',1),('b',4),('c',3),('d',2),('c',4),('d',3),('d',4)] 

यदि ये संरचना उपयोगी हो जाती है तो आप खुद को विकर्ण देख सकते हैं:

 Data.Universe.Helpers> mapM_ print . diagonals $ cartesian2d "abcd" [1..4] [('a',1)] [('a',2),('b',1)] [('a',3),('b',2),('c',1)] [('a',4),('b',3),('c',2),('d',1)] [('b',4),('c',3),('d',2)] [('c',4),('d',3)] [('d',4)] 

यदि आपके पास एक साथ उत्पाद की कई सूचियां हैं, तो फिर से (+*+) वसूली कर सकते हैं; आप अपने एन आयामी कार्टेशियन उत्पाद की जरूरतों के लिए choices :: [[a]] -> [[a]] उपयोग कर सकते हैं।

यहां एन-एरी कार्टेशियन उत्पाद का मेरा कार्यान्वयन है:

 crossProduct :: [[a]] -> [[a]] crossProduct (axis:[]) = [ [v] | v <- axis ] crossProduct (axis:rest) = [ v:r | v <- axis, r <- crossProduct rest ] 

यह sequence आईएनजी के लिए एक नौकरी है इसका एक मोनैडिक कार्यान्वयन हो सकता है:

 cartesian :: [[a]] -> [[a]] cartesian [] = return [] cartesian (x:xs) = x >>= \x' -> cartesian xs >>= \xs' -> return (x':xs') *Main> cartesian [[1,2,3],[4,5,6]] [[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]] 

जैसा कि आप देख सकते हैं, ऊपर से शुद्ध कार्यों के अनुसार map के कार्यान्वयन जैसा दिखता है लेकिन मोनैडाइक प्रकार में। तदनुसार आप इसे सरल करने के लिए नीचे कर सकते हैं

 cartesian :: [[a]] -> [[a]] cartesian = mapM id *Main> cartesian [[1,2,3],[4,5,6]] [[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]]