2017-12-05 10 views
5

हैलो साथी हास्केलर्स।एक आवेदक फंक्शन को कई बार लागू करने के तरीके

मान लें कि मेरे पास एक आवेदक मज़ेदार (मोनैड का उदाहरण नहीं है) I शुद्ध प्रारंभिक मूल्य पर कई बार लागू करना चाहता है। उदाहरण के लिए,

λ> Just (1+) <*> (Just (1+) <*> pure 0) 
Just 2 

मैं लगातार अनुप्रयोगों के किसी भी संख्या को यह सामान्यीकरण करने के लिए चाहते हैं, तो मैं इसे एक fold के साथ क्या कर सकते हैं।

applyAppl :: Applicative f => f (a -> a) -> Int -> f a -> f a 
applyAppl f n i = foldr (<*>) i $ replicate n f 

इस परिभाषा के बाद,

λ> applyAppl (Just (1+)) 10 $ pure 0 
Just 10 

मैं एक अजीब संदेह सामान्यीकरण भी हो सकता है कि इस तरह के sequenceA या traverse के रूप में उच्च क्रम builtin अनुप्रयोगी उपकरणों में से एक के साथ किया है। यह कर सकते हैं?

(। नीचे पहले दो टिप्पणियों को ध्यान में रखना संपादित)

+2

क्या आप उस फ़ंक्शन का प्रकार दे सकते हैं जिसे आप लिखने की कोशिश कर रहे हैं? –

+0

"अधिक आसानी से" से आपका क्या मतलब है? आपका फ़ंक्शन कोड की एक पंक्ति है; यह वास्तव में उससे ज्यादा आसान नहीं मिलता है। – user2407038

+0

आप क्या सरलीकरण करना चाहते हैं? मैंने कुछ सोचने की कोशिश की, लेकिन यह वास्तव में कुछ प्रकार के तह होने के लिए समाप्त हो गया, और आपको फ़ेस को आवेदक से हैक में फ़ंक्शन खींचने के लिए '<*>' पर कॉल करना होगा। – HuStmpHrrr

उत्तर

3

आप का उपयोग iterate सकता है:

applyAppl :: Applicative f => f (a -> a) -> Int -> f a -> f a 
applyAppl f n i = iterate (f <*>) i !! n 

GHCi में लोड किया गया:

ghci> applyAppl (Just (+1)) 10 (pure 0) 
Just 10 

मुझे यकीन है कि है नहीं कर रहा हूँ आपके कार्यान्वयन से जरूरी रूप से बेहतर है, क्योंकि मुझे संदेह है कि दोनों कार्यान्वयन अनिवार्य रूप से एक ही प्रदर्शन प्रोफ़ाइल (हालांकि मैंने इसका परीक्षण नहीं किया है) के साथ कुछ में फ्यूज किया है, लेकिन यह अलग है।

मैंने इस तरह के "iterate(!!) के साथ" स्मृतिकरण के लिए पैटर्न देखा है, इसलिए मुझे पूरा यकीन है कि, कम से कम, इसका खराब प्रदर्शन नहीं होगा।

+0

पहले से ही एक सुधार है, लेकिन अभी भी मुझे इस मामले में 'iterate'' '<*>) की आपूर्ति करने की आवश्यकता है। बस यह समझने की कोशिश कर रहा है कि आवेदक मशीनरी का उपयोग सीधे इसे हल करने के लिए कैसे किया जा सकता है। – jhu

+0

@jhu मुझे पूरा यकीन है कि इसमें कुछ भी नहीं बनाया गया है जो इससे बच जाएगा। मैं गलत हो सकता था (विशेष रूप से क्योंकि यह 2:35 एएम है, हां), लेकिन मैं इस समय कुछ भी नहीं सोच सकता। अंतर्निहित आवेदक कार्यों में से मैं अभी इस बारे में सोच सकता हूं, उनमें से कोई भी "स्टेटसनेस" की आवश्यकता नहीं है (जिस तरह से आपको आवश्यकता है): वे किसी भी तरह से मध्यवर्ती परिणामों का ट्रैक नहीं रखते हैं।तो, उदाहरण के लिए, कुछ (जैसे अनुक्रम (एफएमएपी अनुक्रम (प्रतिकृति एम 10 (बस (+1)))) 0' आपको बस 'बस [1,1,1,1,1,1,1,1 , 1,1] '। –

0

शायद आप @ दाऊद युवा के जवाब के निम्नलिखित बदलाव के लिए देख रहे हैं:

foo :: Applicative f => f (a -> a) -> Int -> a -> f a 
foo f n i = fmap (($ i) . iterateN n) f 
    where iterateN n f = (!! n) . iterate f 

देने:

> foo (Just (1+)) 10 0 
Just 10 
> 

यह "अनुप्रयोगी मशीनरी" applicatives के लिए functor उदाहरण के रूप में उपयोग करता है <*> के स्पष्ट उपयोग के बिना कार्यात्मक पुनरावृत्ति और अनुप्रयोग दोनों को निष्पादित करने के लिए। मुझे यकीन नहीं है कि आप यहां और क्या उम्मीद कर रहे हैं।

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