2011-08-24 8 views
6

मैं निम्नलिखित तरीके से काम करता है रचना करना चाहते हैं:FMAP कांटा कार्यों

compose :: (a->b->c) -> (d->a) -> (d->b) -> d -> c 
compose f g h x = f (g x) (h x) 

ताकि हम निम्नलिखित तरीके से इसका इस्तेमाल कर सकते हैं:

compose (==) (myReverse . myReverse) id [1..100] 

मुझे लगता है कि यह की तरह कुछ के साथ सरल किया जा सकता है 'fmap', ताकि इसे 'compose' को परिभाषित करने की आवश्यकता न हो। लेकिन मैं यह समझने में नाकाम रहा कि यह कैसे करना है।

+0

जो आपने प्रदान किया है वह सबसे सरल और सबसे पठनीय समाधान है। इसके लिए अन्य तथाकथित "घने" कोड समाधान हो सकते हैं, लेकिन मैं सरल और पठनीय कोड पसंद करता हूं :) – Ankur

उत्तर

11

आप Control.Applicative

compose f g h = f <$> g <*> h 

तो आयात करते हैं, तो, यदि आप लिख सकते हैं (==) <$> (myReverse . myReverse) <*> id $ [1..100]

<*> विशेष कार्य के लिए S-combinator के बराबर है:

s f g x = f x (g x) 

आप शायद Control.Arrow भी उपयोग कर सकते हैं :

compose f g h = g &&& h >>> uncurry f 
test = uncurry (==) <<< (myReverse <<< myReverse) &&& id $ [1..100] 

अद्यतन

मैं #haskell वही सवाल पर lambdabot पूछा है और वह बस liftM2 जवाब दे दिया। : डी

+0

+1, अच्छा जवाब। अर्ध-नोब के रूप में मैंने स्वयं दोनों समाधानों को प्राप्त करने की कोशिश की, बहुत करीब हो गया लेकिन इसे नहीं बनाया (मुझे 'uncurry' के साथ लिखने के लिए '<<<' याद आया)। –

+0

वास्तव में '<<<' '.' के बराबर है। यह '&&&' है जो नौकरी करता है (तर्क को विभाजित करता है)। – Rotsor

+1

मुझे पता है कि '<<<' संरचना है, लेकिन मैं 'uncurry (==) ((रिवर्स। रिवर्स) &&& आईडी) $ [1..100]' के साथ अटक गया, जो हिंडसाइट में बेवकूफ है। –

संबंधित मुद्दे