हास्केल में, मैं आसानी से एक सूची मैप कर सकते हैं:हास्केल: टुपल को कैसे मैप करें?
map (\x -> 2*x) [1,2]
मुझे [2,4]
देता है। क्या कोई "मैपटुप" फ़ंक्शन है जो इस तरह काम करेगा?
mapTuple (\x -> 2*x) (1,2)
परिणामस्वरूप (2,4)
है।
हास्केल में, मैं आसानी से एक सूची मैप कर सकते हैं:हास्केल: टुपल को कैसे मैप करें?
map (\x -> 2*x) [1,2]
मुझे [2,4]
देता है। क्या कोई "मैपटुप" फ़ंक्शन है जो इस तरह काम करेगा?
mapTuple (\x -> 2*x) (1,2)
परिणामस्वरूप (2,4)
है।
Searching at Hoogle(a -> b) -> (a, a) -> (b, b)
, जो प्रकार आप की आवश्यकता है के लिए कोई सटीक मिलान देता है, लेकिन यह काफी अपने आप को ऐसा करने के लिए आसान है:
mapTuple :: (a -> b) -> (a, a) -> (b, b)
mapTuple f (a1, a2) = (f a1, f a2)
ध्यान दें, आप 3-tuples के लिए एक नया समारोह को परिभाषित करना होगा, 4-ट्यूपल्स इत्यादि - यद्यपि ऐसी आवश्यकता एक संकेत हो सकती है, कि आप टुपल्स का उपयोग नहीं कर रहे हैं जैसे कि उनका इरादा था: आम तौर पर, टुपल्स को विभिन्न प्रकार के मान होते हैं, इसलिए सभी मानों पर एक ही फ़ंक्शन लागू करना चाहते हैं, यह बहुत आम नहीं है।
हाँ, आप क्या करेंगे:
map (\x -> (fst x *2, snd x *2)) [(1,2)]
fst
एक टपल में पहली डेटा प्रविष्टि पकड़ लेता है, और snd
दूसरा पकड़ लेता है; इसलिए, कोड की रेखा कहती है "एक ट्यूपल लें, और पहले और दूसरी वस्तुओं के साथ एक और टुपल वापस करें।"
आपका कोड काम नहीं करता है, लेकिन एक साइड नोट के रूप में याद रखें कि आप लैम्बडा फ़ंक्शन के तर्कों पर पैटर्न मिलान कर सकते हैं : '\ (x, y) -> (x * 2, y * 2)' – danr
@danr - मुझे एक कोष्ठक याद आ रहा था, इसे इंगित करने के लिए धन्यवाद: पी। मुझे पैटर्न मिलान के बारे में पता नहीं था, धन्यवाद! –
@danr यह मेरे लिए काम करता है। –
आप मॉड्यूल Control.Arrow
से arrows का उपयोग कर सकते हैं जो टुपल्स पर काम करने वाले कार्यों को लिखने के लिए करते हैं।
Prelude Control.Arrow> let f = (*2) *** (*2)
Prelude Control.Arrow> f (1,2)
(2,4)
Prelude Control.Arrow> let f' = (*2) *** (*3)
Prelude Control.Arrow> f (2,2)
(4,4)
Prelude Control.Arrow> f' (2,2)
(4,6)
आपका mapTuple तो हो जाता है
mapTuple f = f *** f
अगर आपका प्रश्न आप एक समारोह है कि मनमाने ढंग से arity की tuples की मानचित्रों के लिए कहा साथ, तो मुझे डर लग रहा तुम नहीं है क्योंकि वे विभिन्न प्रकार के लिए होता कर सकते हैं (उदाहरण के लिए ट्यूपल प्रकार (a,b)
और (a,b,c)
पूरी तरह से अलग और असंबंधित हैं)।
क्या मुझे उनका उपयोग करने के लिए मॉड्यूल लोड करने की आवश्यकता है? सादा प्रस्ताव में आपका कोड काम नहीं करता है। –
हाँ, आप करते हैं, आपको 'Control.Arrow' की आवश्यकता है। मैंने अपना जवाब अपडेट किया। –
आप Bifunctor
इस्तेमाल कर सकते हैं:
import Control.Monad (join)
import Data.Bifunctor (bimap)
join bimap (2*) (1,2)
यह रूप में अच्छी तरह से काम करता है न केवल जोड़े के लिए है, लेकिन अन्य प्रकार के एक नंबर के लिए, उदाहरण के लिए Either
के लिए।
Bifunctor
संस्करण 4.8 के रूप में base में है। पहले इसे bifunctors पैकेज द्वारा प्रदान किया गया था।
'(->)' monad उदाहरण के लिए 'join' चाल अद्भुत है। धन्यवाद! – Profpatsch
अच्छा! जो मुझे किसी अन्य संदर्भ में मिला, वह धड़कता है, जहां मैं केवल दूसरे मान को संशोधित करना चाहता था, यानी आयात 'डेटा.ग्राफ.इंडक्टिव.Query.मोनाड' और फिर '(* 2)><(* 2) 'यह फ़ंक्शन है बाद में (मुझे परेशान है कि यह डेटा में नहीं है। ठीक है, लेकिन शायद यह इतिहास का दुर्घटना है।) –
यहाँ एक नहीं बल्कि छोटे बिंदु से मुक्त समाधान है:
import Control.Monad (join)
import Control.Arrow ((***))
mapTuple = join (***)
फ़ंक्शंस पर उपयोग किए जाने पर शामिल होने का क्या प्रभाव है? –
@ रिकार्डो - 'जॉइन' एक ही प्रकार, 'ए-> ए-> बी' के साथ दो तर्कों का एक फ़ंक्शन लेता है, और एक तर्क' ए -> बी' के साथ एक नया फ़ंक्शन बनाता है, जो दोनों पदों के लिए उस तर्क को पास करता है मूल कार्य ऐसा इसलिए है क्योंकि फ़ंक्शंस के लिए मोनाड इंस्टेंस 'रीडर' मोनैड के समान है, 'join' type' (a -> a -> b) -> a -> b' दे रहा है। जब तीर इंफिक्स नहीं लिखा जाता है, तो मुझे यह काम करना थोड़ा आसान लगता है, उदा। 'शामिल हों :: (ए ->) ((ए ->) बी) -> (ए ->) बी'। –
@ जॉन: धन्यवाद! –
इस रंगीन सेट करने के लिए एक और समाधान जोड़ने के लिए ... तुम भी अधिक मनमाना एन-tuples Scrap-Your-Boilerplate generic programming का उपयोग कर देख सकते हैं।उदाहरण के लिए:
import Data.Data
import Data.Generics.Aliases
double :: Int -> Int
double = (*2)
tuple :: (Int, Int, Int, Int)
tuple = gmapT (mkT double) (1,2,3,4)
ध्यान दें कि स्पष्ट प्रकार की टिप्पणियां महत्वपूर्ण हैं, क्योंकि SYB प्रकार के अनुसार फ़ील्ड का चयन करता है। यदि कोई एक tuple तत्व प्रकार Float
बनाता है, उदाहरण के लिए, अब यह दोगुना नहीं होगा।
मैं अस्पष्टता से समझता हूं कि मूल/एसबीएलर में कुछ समर्थन के साथ जीएचसी जेनरिक द्वारा कई मूल एसवाईबी पुस्तकालयों को प्रतिस्थापित किया गया है। (लेकिन हो सकता है कि आप और वह विकिपीडिया पृष्ठ सामान्य रूप से जेनेरिक के लिए एक शब्द "एसवाईबी" का उपयोग करें, न केवल विशिष्ट मूल एसवाईबी कागजात ...) – misterbee
मैं गलत हो सकता हूं, लेकिन जीएचसी के ['डेटा। डेटा 'दस्तावेज] (http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Data.html) SYB को उद्धृत करता है, मैं डरता हूं कि यह प्रत्यक्ष वंशज है। –
तुम भी Applicatives जो प्रत्येक टपल तत्व के लिए विभिन्न कार्यों को लागू करने के आप संभावना देने के अतिरिक्त लाभ भी उठा उपयोग कर सकते हैं:
import Control.Applicative
mapTuple :: (a -> a') -> (b -> b') -> (a, b) -> (a', b')
mapTuple f g = (,) <$> f . fst <*> g . snd
इनलाइन संस्करण:
(\f -> (,) <$> f . fst <*> f . snd) (*2) (3, 4)
या अलग नक्शे कार्यों के साथ और बिना लैम्ब्डा:
(,) <$> (*2) . fst <*> (*7) . snd $ (3, 4)
अन्य संभावना तीर का उपयोग करने के होगा:
mapPair :: (a -> b) -> (a, a) -> (b, b) -- this is the inferred type
mapPair f = uncurry ((,) `on` f)
आप Data.Function
on
समारोह के लिए आयातित की जरूरत है:
import Control.Arrow
(+2) . fst &&& (+2) . snd $ (2, 3)
यहाँ एक और तरीका है।
मुझे लगता है कि यह सबसे सरल और सबसे सुरुचिपूर्ण समाधान है। प्रत्येक 0 से अधिक – hololeap
मैंने अभी इस पैकेज को हल करने वाले हैकेज में पैकेज tuples-homogenous-h98 जोड़ा है। यह newtype
रैपर को टुपल्स के लिए जोड़ता है और Functor
, Applicative
, Foldable
और Traversable
उनके लिए उदाहरण परिभाषित करता है। पैकेज का उपयोग करके आप की तरह कर सकते हैं:
untuple2 . fmap (2 *) . Tuple2 $ (1, 2)
तरह
या ज़िप tuples:
Tuple2 ((+ 1), (*2)) <*> Tuple2 (1, 10)
extra पैकेज फ़ंक्शन Data.Tuple.Extra मॉड्यूल में प्रदान करता है। डॉक्स से:
Apply a single function to both components of a pair.
> both succ (1,2) == (2,3)
both :: (a -> b) -> (a, a) -> (b, b)
uniplate पैकेज Data.Generics.Uniplate.Data मॉड्यूल में descend समारोह प्रदान करता है। यह फ़ंक्शन हर प्रकार के मिलान के फ़ंक्शन को लागू करेगा, इसलिए सूचियों, tuples, या तो, या अन्य सभी डेटा प्रकारों पर लागू किया जा सकता है। कुछ उदाहरण:
descend (\x -> 2*x) (1,2) == (2,4)
descend (\x -> 2*x) (1,"test",Just 2) == (2,"test",Just 4)
descend (\x -> 2*x) (1,2,3,4,5) == (2,4,6,8,10)
descend (\x -> 2*x) [1,2,3,4,5] == [2,4,6,8,10]
बीटीडब्ल्यू, सूची में एक साधारण गुणा को मैप करने के लिए लैम्ब्स का उपयोग करने की आवश्यकता नहीं है: बस 'नक्शा (* 2) [1,2,3] 'चाल चल जाएगा। –
ध्यान दें कि इससे कोई फर्क नहीं पड़ता कि आप इसे कैसे कार्यान्वित करते हैं, यह केवल प्रकार के साथ टुपल्स पर काम करेगा: (ए, ए) – hololeap