2010-12-03 18 views
5

मुझे एक फ़ंक्शन 'कंपोज़' परिभाषित करने की आवश्यकता है जो एक सूची 'एल' लेती है जो कार्यों की एक सूची है। जब मैं एक पैरामीटर निर्दिष्ट करता हूं जो सूची में सभी कार्यों के अनुरूप होगा, अंतिम फ़ंक्शन इस पैरा का उपयोग करके स्वयं का मूल्यांकन करता है। नतीजा तब दूसरे अंतिम समारोह में पारित किया जाता है और तब तक जब तक हम सूची में पहले आइटम (फ़ंक्शन) तक नहीं पहुंच जाते हैं और हमें अंतिम परिणाम मिलता है।कार्यों की सूची में कार्यों की संरचना!

उदा।

लिखें ((एफएन एन -> एन + 1)^(एफएन एन -> 2 * एन)^#) 3।

जवाब 7.

दे रहा साल (सरल अनुप्रयोगी भाषा) नामक एक कार्यात्मक प्रोग्रामिंग भाषा मेरे कॉलेज में एक व्याख्याता द्वारा तैयार (ऊपर इसलिए अजीब वाक्य रचना में यह लिखने के लिए है (^ सूची आइटम और # निशान अलग सूची का अंत))।

यदि कोई समाधान छद्म कोड में दिमाग में लिखा जा सकता है तो मैं लूप, चर आदि का उपयोग नहीं कर सकता हूं, जिसकी बहुत सराहना की जाएगी। स्पष्ट रूप से समाधान एक पंक्ति का जवाब है। मुझे कल्पना है कि इसमें रिकर्सन शामिल है (हमारे कार्य कार्यों का 99% करते हैं!)।

मैं भी हास्केल को समझ नहीं पा रहा हूं (अनुमान है कि मुझे सीखना होगा!) तो psuedo कोड या यहां तक ​​कि सादे अंग्रेजी भी महान होगी। -

धन्यवाद एक गुच्छा।

उत्तर

3
हास्केल में

:

compose :: a -> [a -> a] -> a 
compose a (x:xs) = x (compose a xs) 
compose a [] = a 
1

दान तरह का इसे दूर कर देता है, लेकिन यहाँ है कि यह कैसे अपने आप को ऐसा करने के लिए पर एक संकेत है। आप संख्याओं पर भर्ती कर सकते हैं:

0! = 1 
n! = (n-1)! * n 

आप संरचना पर भी भर्ती कर सकते हैं। उदाहरण के लिए, एक सूची में एक पुनरावर्ती संरचना है, जो दो मामलों में विभाजित है: एक खाली सूची, और बाकी की सूची के बाद एक आइटम। कोई विशेष भाषा में:

List := Item x List 
     | Nil 

Item सूची के सिर के निशान, x सिर में संग्रहीत मूल्य है, और List पूंछ है। इस व्याकरण में, अपनी सूची लिखा जाएगा:

Item (fn N -> N + 1) Item (fn N -> 2 * N) Nil 

वाक्य रचना अपने प्रोफेसर आविष्कार रिकर्सिवली लिखा जा सकता है में एक सूची के लिए नियम के रूप में:

List := x^List 
     | # 

एक सूची पर एक समारोह इस पर recurse चाहिए संरचना है, जो इसे दो मामलों में से प्रत्येक हैंडल का अर्थ है:

sum l:List = Nil -> 0 
      | Item x xs:List = x + sum xs 

प्रत्यावर्तन, विशेष रूप से, अवधि sum l:List = x + sum xs है। एक अभ्यास के रूप में छोड़ दिया प्रोफेसर के वाक्यविन्यास का उपयोग कर इस समारोह को लिखना।

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

14

समाधान एक पंक्ति जवाब है, तो यह एक गुना से जुड़ी कोई भी हो सकता है:

compose :: [a -> a] -> a -> a 
compose fs v = foldl (flip (.)) id fs $ v 

http://haskell.org/haskellwiki/Compose

तुम भी एक सही गुना है, जो जिस तरह से आप चाहते हैं काम करता है के रूप में यह लागू कर सकते हैं :

compose = foldr (.) id 

*Main> let compose = foldr (.) id 
*Main> compose [\x -> x+1, \x -> 2 * x, id] 3 
7 
+0

, $ अनावश्यक है, और वजह आप इसे पसंद pointfree लिखने के लिए चाहते हो सकता है यह: 'compose = foldl (फ्लिप (।)) आईडी'। – HaskellElephant

+0

टिप्पणी के लिए धन्यवाद, लेकिन यह वास्तव में मेरा समाधान नहीं था, लेकिन मैंने पोस्ट किए गए लिंक से कॉपी किया। –

+1

सही फ़ोल्डर्स आमतौर पर इस विशेष प्रकार की चीज़ के लिए बेहतर होते हैं यदि उनके पास वांछित अर्थशास्त्र - आलसी और अधिक कुशल होता है। – dfeuer

0

यहाँ मैं क्या इस्तेमाल किया है:

compose :: [a -> a] -> a -> a 
compose list startingvalue = foldl (\x f -> f x) startingvalue list 
0

ही monoids का उपयोग कर, pointfree

import Data.Monoid 
compose :: [a -> a] -> a -> a 
compose = appEndo . mconcat . map Endo 

या कुछ और अधिक आम तौर पर:

import Data.Monoid 
compose :: (Functor t, Foldable t) => t (a -> a) -> a -> a 
compose = appEndo . foldl1 (<>) . fmap Endo 
अपने पहले संस्करण में
+2

हू? क्यों न सिर्फ 'लिखें :: Foldable टी => टी (ए -> ए) -> ए -> ए; compose = appEndo। FoldMap एंडो'? – dfeuer

+0

यह भी अच्छा है, संकेत देने के लिए धन्यवाद! – user1747134

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