2015-09-24 6 views
6

मैं इस तरह एक समारोह में सोच रहा हूँ:क्या कई बार एक परिवर्तन लागू करने के लिए एक मानक उच्च आदेश समारोह है?

> let applyN (initial : 't) (n:int) (f : 't -> 't) = seq {1..n} |> Seq.fold (fun s _ -> f s) initial;; 

val applyN : initial:'t -> n:int -> f:('t -> 't) -> 't 

> applyN 0 10 (fun x -> x + 1);; 
val it : int = 10 

नोट: कोड एफ # है, लेकिन मैं Haskell, ocaml और मिलीलीटर टैग के साथ सवाल में चिह्नित क्योंकि अगर समारोह एफ # पुस्तकालयों में मौजूद नहीं है, लेकिन यह अन्य भाषाओं में मौजूद है, मैं उसी नाम का उपयोग करना चाहता हूं

+6

downvoters में से एक की व्याख्या क्या समस्या यहाँ है कृपया कर सकते हैं? सवाल मेरे लिए अच्छा लगता है। यहां एफपी उप-समुदाय आमतौर पर वास्तव में अनुकूल होते हैं और मुझे उम्मीद है कि हम इसे इस तरह से रख सकते हैं, इसलिए कम से कम प्रश्न आपकी राय में क्यों बुरा है। – Carsten

+1

मुझे लगता है कि आपको प्रति भाषा एक प्रश्न पोस्ट करना चाहिए, क्योंकि भविष्य के लोग शायद एक जवाब खोज लेंगे। मुख्य रूप से, मैं कहूंगा कि आपका प्रश्न अलग-अलग उत्तरों की अपेक्षा करता है, तो आपको इसे विभाजित करना चाहिए। – PatJ

+2

@ करस्टन मॉडरेशन शोर के स्तर इस समय सामान्य से अधिक प्रतीत होते हैं। पिछले कुछ दिनों में मैंने न केवल अजीब डाउनवॉट्स बल्कि कम से कम दो [हैकेल] प्रश्नों में बेतुका करीबी मतों को देखा है। – duplode

उत्तर

6

आप प्राप्त होंगे उदाहरण Hayoo के लिए का उपयोग करके एक जवाब (बहुत के करीब) परिभाषित कर सकते हैं कर सकते हैं (या Hoogle, लेकिन Hoogle के रूप में लचीला नहीं है - iterateN नहीं मिला था):

  • Int -> (a -> a) -> a -> a के लिए एक खोज कई कार्य है कि आप क्या चाहते हैं लेकिन stdlib का हिस्सा नहीं हैं का पता चला।

  • applyN के लिए एक खोज उसी प्रकार के फ़ंक्शन को लौटा दी जिस प्रकार आप देख रहे हैं हस्ताक्षर के साथ।

  • Int -> (a -> a) -> a बजाय की खोज करके वापसी मान laxing द्वारा (ध्यान दें अंत में लापता -> a), तो आपको iterateN :: Int -> (a -> a) -> a -> Seq a समारोह जो erdeszt पहले ही उल्लेख किया गया है मिलता है।

पीएस होउगल तर्क आदेश के चारों ओर फ़्लिप करने में सक्षम होने लगता है: (a -> a) -> Int -> a -> Seq a सफलतापूर्वक 'iterateN :: Int -> (a -> a) -> a -> seq a` देता है, जो Hayoo नहीं करता है।

+1

मुझे नहीं पता था कि आप हस्ताक्षर से खोज सकते हैं। Hayoo के लिंक के लिए धन्यवाद! – vidi

3

Data.Sequence मॉड्यूल में हास्केल के लिए एक इटरेटन फ़ंक्शन है जो आप ढूंढ रहे हैं जैसा दिखता है।

यह वास्तव में सिर्फ पुनरावृति की एक combinaton है + ले:

let rec iterate f value = seq { 
    yield value 
    yield! iterate f (f value) } 
+0

iterateN में हस्ताक्षर नहीं है जिसे मैं ढूंढ रहा हूं। फ़ंक्शन को अंतिम मान वापस करना चाहिए, अनुक्रम – vidi

+0

@vidi आप हमेशा अंतिम तत्व ले सकते हैं (या आप इसे पूरे शेबैंग को इनरेटन के अंदर रेखांकित कर सकते हैं और आपको संग्रह बनाने की आवश्यकता नहीं है)। – erdeszt

1

सम्भावित समाधान:

let iterateN n f x = take n (iterate f x) यहाँ पुनरावृति ( from here) के एक एफ # संस्करण है, Seq.take एफ # मानक पुस्तकालय का हिस्सा है
> import Data.Monoid 
> import Debug.SimpleReflect -- not really needed, just for showing the result 
> (appEndo . mconcat . replicate 5 . Endo $ f) a 
f (f (f (f (f a)))) 

एक और (पहले ही उल्लेख किया):

> iterate f a !! 5 
f (f (f (f (f a)))) 

(lambdas जोड़ने आप इसे एक समारोह में बदल करना चाहते हैं)

हालांकि, मत भूलना कि हास्केल आलसी है: उपरोक्त विधियों पहले f कई बार लगाने से एक thunk का निर्माण करेगा और उसके बाद ही मूल्यांकन कर शुरू करते हैं। कभी-कभी f निरंतर स्थान में पुनरावृत्त किया जा सकता है, उदा। जब f :: Int -> Int (और f स्वयं स्थिर स्थान में काम करता है), लेकिन उपर्युक्त दृष्टिकोण केवल रैखिक स्थान में काम करते हैं।

मैं खुद सख्त यात्रा Combinator द्वारा परिभाषित करेगा, उदा .:

iter :: Int -> (a -> a) -> a -> a 
iter 0 _ x = x 
iter n f x = iter (pred n) f $! f x 

या यहाँ तक कि,

iter n f x = foldl' (flip $ const f) x [1..n] 

जो कम क्या पहले से ही विचाराधीन पोस्ट किया गया की हास्केल अनुवाद की अधिक है।

वैकल्पिक रूप से, हम iterate की एक सख्त संस्करण (जो IMHO पहले से मौजूद हो ...)

iterate' :: (a -> a) -> a -> [a] 
iterate' f x = x : (iterate' f $! f x) 
0

यह करने के लिए अन्य तरीकों की सूची में जोड़ने के लिए,

import Control.Monad.State.Lazy 

applyN initial n = 
    flip execState initial . replicateM_ n . modify 
संबंधित मुद्दे