2010-12-10 29 views
13

क्या हास्केल के लिए समीकरण विस्तारक मौजूद है?हास्केल: समीकरण विस्तारक 1+ (1+ (1+ (1+ (...))) = ∞

कुछ foldr.com की तरह: 1+(1+(1+(1+(…))))=∞

मैं Haskell करने के लिए मैं मुसीबत समझ क्यों कुछ समीकरणों दूसरों की तुलना में अधिक बेहतर हैं हो रहा है नया हूँ। मुझे लगता है कि अगर मैं समीकरणों को विस्तारित देख सकता हूं तो इससे मदद मिलेगी।

उदाहरण के लिए मैंने foldr बनाम foldl को तब तक समझना मुश्किल था जब तक कि मैंने उन्हें विस्तारित नहीं किया।

foldr :: (a -> b -> b) -> b -> [a] -> b 
foldr k z xs = go xs 
      where 
       go []  = z 
       go (y:ys) = y `k` go ys 

foldl :: (a -> b -> a) -> a -> [b] -> a 
foldl f z0 xs0 = lgo z0 xs0 
      where 
       lgo z []  = z 
       lgo z (x:xs) = lgo (f z x) xs 

परिभाषाओं से मैं देख सकता हूँ कि foldr इस तरह फैलता है:

foldr (+) 0 [1..1000000] --> 
1 + (foldr (+) 0 [2..1000000]) --> 
1 + (2 + (foldr (+) 0 [3..1000000])) --> 
1 + (2 + (3 + (foldr (+) 0 [4..1000000]))) --> 
1 + (2 + (3 + (4 + (foldr (+) 0 [5..1000000])))) --> 

और foldl इस तरह फैलता है:

foldl (+) 0 [1..1000000] --> 
foldl (+) (foldl (+) 0 [1]) [2..1000000]) --> 
foldl (+) (foldl (+) (foldl (+) 0 [1])) [3..1000000]) --> 

या Haskell Wiki on foldr fold foldl' से:

let z1 = 0 + 1 
in foldl (+) z1 [2..1000000] --> 

let z1 = 0 + 1 
    z2 = z1 + 2 
in foldl (+) z2 [3..1000000] --> 

let z1 = 0 + 1 
    z2 = z1 + 2 
    z3 = z2 + 3 
in foldl (+) z3 [4..1000000] --> 

let z1 = 0 + 1 
    z2 = z1 + 2 
    z3 = z2 + 3 
    z4 = z3 + 4 
in foldl (+) z4 [5..1000000] --> 

हालांकि, मुझे बड़े समीकरणों को समझने में परेशानी है कि चीजें हास्केल में जिस तरह से काम करती हैं। उदाहरण के लिए पहला चलनी फ़ंक्शन 1000 फ़िल्टर का उपयोग करता है जबकि दूसरा चलनी फ़ंक्शन 1001 प्राइम ढूंढने के लिए केवल 24 लेता है।

primes = sieve [2..] 
    where 
    sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0] 



primes = 2: 3: sieve (tail primes) [5,7..] 
    where 
    sieve (p:ps) xs = h ++ sieve ps [x | x <- t, rem x p /= 0] 
            -- or: filter ((/=0).(`rem`p)) t 
         where (h,~(_:t)) = span (< p*p) xs 

Haskell Wiki on Primes

मैं एक अच्छा खर्च किया है काम कर रहे हैं और हाथ से विस्तार हो रहा है। मुझे समझ में आया है कि यह कैसे काम करता है। हालांकि, कुछ अभिव्यक्तियों का विस्तार करने के लिए एक स्वचालित उपकरण हास्केल की मेरी समझ में काफी सुधार करेगा।

इसके अलावा मुझे लगता है कि यह भी सवाल है कि हास्केल कोड अनुकूलन करने के लिए की तलाश में मदद करने के सेवा कर सकता है:

वहाँ हास्केल भाव का विस्तार करने के लिए एक उपकरण है?

+1

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

+1

+1 - अच्छी पोस्ट। –

उत्तर

3

यह कोई रास्ता नहीं अपने प्रश्न के लिए एक पूर्ण उत्तर में है, लेकिन मैं कुछ उत्तर है कि हास्केल-कैफे पर एक बातचीत पाया:

http://www.haskell.org/pipermail/haskell-cafe/2010-June/078763.html

इस पैकेज के लिए कि धागा लिंक:

http://hackage.haskell.org/package/repr कि पेज के अनुसार, "आप उनके शाब्दिक प्रतिनिधित्व करने के लिए अतिभारित भाव से रेंडर होने देता"

आपूर्ति की गई उदाहरण है:

*Repr> let rd = 1.5 + 2 + (3 + (-4) * (5 - pi/sqrt 6)) :: Repr Double 
*Repr> show rd 
"fromRational (3 % 2) + 2 + (3 + negate 4 * (5 - pi/sqrt 6))" 
4

डेविड वी। उन लिंक के लिए धन्यवाद। Repr निश्चित रूप से मेरे टूल बॉक्स में जोड़ने लायक है। मैं कुछ अतिरिक्त पुस्तकालयों को जोड़ना चाहता हूं जो मुझे उपयोगी लगे।

HackageDB : Trace (12 दिसंबर 2010 तक)

  • GHC-घटनाओं पुस्तकालय और कार्यक्रम: पुस्तकालय और
  • हुड पुस्तकालय GHC से .eventlog फ़ाइलों को पार्स करने उपकरण: जगह
  • में देख कर डिबगिंग
  • एचपीसी स्ट्रोब पुस्तकालय: एक चल हास्केल कार्यक्रम
  • एचपीसी ट्रेसर कार्यक्रम के लिए एचपीसी उत्पन्न strobes: AJAX के इंटरफेस के साथ ट्रेसर

हुक पैकेज ऐसा लगता है जो मैं ढूंढ रहा हूं। मैं आज बाद में अधिक नमूने पोस्ट करूंगा।

Hood

main = runO ex9 

ex9 = print $ observe "foldl (+) 0 [1..4]" foldl (+) 0 [1..4] 

आउटपुट

10 

-- foldl (+) 0 [1..4] 
    { \ { \ 0 1 -> 1 
     , \ 1 2 -> 3 
     , \ 3 3 -> 6 
     , \ 6 4 -> 10 
     } 0 (1 : 2 : 3 : 4 : []) 
     -> 10 
    } 

मैं Hackage पुस्तकालय से अनजान थे (के रूप में मैं सिर्फ हास्केल में हो रही है)। यह मुझे पर्ल के सीपीएएन की याद दिलाता है। उन लिंक प्रदान करने के लिए धन्यवाद। यह एक उत्कृष्ट संसाधन है।

1

यह एक अनसुलझा प्रश्न का उत्तर है, इसे एक लंबी टिप्पणी के रूप में सोचें।

(कृपया उसके बाद ही 0 नीचे downvote, iff आपको लगता है कि यह मेल नहीं खाती। मैं तब से निकाल देंगे।)


जैसे ही आप में थोड़ा और अधिक अनुभवी हैं, तो आप नहीं हो सकता है चीजों का विस्तार करने के तरीके को देखना चाहते हैं। आप समझना चाहेंगे कि चीजें कैसे काम करती हैं, जो तब प्रश्न पूछती है कि यह क्यों काम करती है; आप यह देखकर बहुत कुछ हासिल नहीं करेंगे कि यह कैसे विस्तार करता है।

कोड का विश्लेषण करने का तरीका आपके विचार से कहीं अधिक सरल है: बस अपने पैरामीटर कनेक्शन के प्रगति के आधार पर प्रत्येक पैरामीटर/चर या तो "मूल्यांकन" या "अनियमित" या "मूल्यांकन किया जाना" के रूप में लेबल करें ।

दो उदाहरण:


1.) fibs

सभी फाइबोनैचि संख्या की सूची

fibs :: (Num a) => [a] 
fibs = 1 : 1 : zipWith (+) fibs (tail fibs) 

पहले दो तत्व पहले से ही मूल्यांकन कर रहे हैं; इसलिए, तीसरे तत्व को लेबल करें (जिसमें मूल्य 2 है) मूल्यांकन के रूप में और शेष सभी अव्यवस्थित के रूप में शेष हैं। तीसरा तत्व तब (+) होगा - फाइब्स और पूंछ फाइब्स के पहले तत्वों का संयोजन, जो कि फाइबर का पहला और दूसरा तत्व होगा, जिसे पहले ही मूल्यांकन के रूप में लेबल किया गया है। यह n-th तत्व से-मूल्यांकन और (n-2) -nd और (n-1)-क्रमशः पहले से मूल्यांकन किए गए तत्वों के साथ काम करता है।

आप इसे विभिन्न तरीकों से कल्पना कर सकते हैं, यानी।:

fibs!!(i+0) 
+ fibs!!(i+1) 
= fibs!!(i+2) 

      (fibs) 
zipWith(+) (tail fibs) 
     = (drop 2 fibs) 

      1 : 1 : 2 : 3 ... 
    (1 :)1 : 2 : 3 : 5 ... 
(1 : 1 :)2 : 3 : 5 : 8 ... 

2.) आपका उदाहरण "चलनी (पी: पी एस) XS"

primes = 2: 3: sieve (tail primes) [5,7..] 
    where 
    sieve (p:ps) xs = h ++ sieve ps [x | x <- t, rem x p /= 0] 
            -- or: filter ((/=0).(`rem`p)) t 
         where (h,~(_:t)) = span (< p*p) xs 

में "चलनी (पी: पी एस) XS",

  • पी मूल्यांकन किया गया है,
  • ps अनियमित है, और
  • xs एक मूल्यांकन अनंत आंशिक-स्कीव सूची है (पी युक्त नहीं है लेकिन जिसमें पी² है), जिसे आप रिकर्सन और/या पहचानने का अनुमान लगा सकते हैं कि एच के मूल्यों को प्राइम होने की आवश्यकता है।

चलनी को पी के बाद प्राइम्स की सूची वापस करनी चाहिए, इसलिए कम से कम अगले प्रधान का मूल्यांकन किया जाना चाहिए।

  • अगले प्रधानमंत्री में सूची ज है, जो सभी (पहले से ही sieved) नंबर की सूची है हो जाएगा k जहां पी < कश्मीर < p²; एच में केवल प्राइम होते हैं क्योंकि xs में न तो पी होता है और न ही किसी भी संख्या के नीचे किसी भी प्राइम द्वारा विभाजित किया जाता है।
  • टी में पी² के ऊपर xs की सभी संख्याएं शामिल हैं। टी जल्द से जल्द आलसी मूल्यांकन किया जाना चाहिए, क्योंकि एच में सभी तत्वों का मूल्यांकन करने की आवश्यकता भी नहीं हो सकती है।

समारोह परिभाषा के बाकी प्रत्यावर्तन, जहां अगले XS सभी n * पी के साथ टी है बाहर sieved है (केवल एच के पहले तत्व होने से मूल्यांकन किया है।)।


foldr के मामले में, एक विश्लेषण दिखाएगा कि "जाओ" केवल क्रम, नहीं पठनीयता तेजी लाने के लिए परिभाषित किया गया है। यहाँ एक वैकल्पिक परिभाषा यह है कि विश्लेषण करने के लिए आसान है,:

foldr :: (a -> b -> b) -> b -> [a] -> b 
foldr (.:) e (x:xs) = x .: (foldr (.:) e xs) 
foldr (.:) e []  = e 

मैं here (विश्लेषण) के बिना अपनी कार्यक्षमता का वर्णन किया है।

इस प्रकार के विश्लेषण को प्रशिक्षित करने के लिए, आप कुछ मानक पुस्तकालयों के स्रोतों को पढ़ना चाहेंगे; यानी Data.List के source में स्कैनल, स्कैनर, unfoldr।

+1

फ़ंक्शन (। :) का क्या अर्थ है? –

+1

(। :) प्रकार का एक पैरामीटर है (ए-> बी-> बी)। यदि आप f के साथ (। :) को प्रतिस्थापित करते हैं, तो आपको प्रतिस्थापित करना होगा।: \ 'F \' के साथ। – comonad