2010-08-04 10 views
5

मैं हाल ही में हास्केल सीख रहा हूं और एसआईसीपी के माध्यम से काम कर रहे एक दोस्त से बात कर रहा था। हम आम लिस्प और योजना की तुलना करने के लिए उत्सुक थे और इसलिए मैंने व्यायाम 1.2 9 को हास्केल में अनुवाद करने का प्रयास करने के लिए एक अभ्यास के रूप में निर्णय लिया।एसआईसीपी अभ्यास में हास्केल न्यूमेरिक टाइप पदानुक्रम

यह अभ्यास एक फ़ंक्शन सिग्मा का उपयोग करता है जो गणितीय सारांश समारोह सिग्मा का प्रतिनिधित्व करता है। यह कार्य प्रत्येक कार्यकाल, निचली बाध्य, प्रत्येक कार्यकाल को अगले कार्यकाल और ऊपरी बाउंड प्राप्त करने के लिए लागू करने के लिए एक फ़ंक्शन पर लागू करने के लिए एक फ़ंक्शन f लेता है। यह प्रत्येक अवधि पर लागू एफ की राशि देता है।

सिम्पसन इंटेग्रल को "सटीकता" एन का उपयोग करके सीमा [ए, बी] पर फ़ंक्शन f के अभिन्न अंग का अनुमान लगाने के लिए सिम्पसन के नियम का उपयोग करना चाहिए। मुझे इस कार्य को काम करने में परेशानी हो रही है क्योंकि ऐसा लगता है कि मैं शामिल प्रकारों के बारे में कुछ नहीं समझता।

यह कोड ghc के संस्करण 6.12.1 के साथ संकलित करेगा लेकिन सिम्पसन इंटेग्रल को एक प्रकार का संदर्भ दिया जाएगा (इंटीग्रल ए, फ्रैक्शनल ए) जो कोई समझ नहीं लेता है और जैसे ही आप इसे कॉल करते हैं, फ़ंक्शन उड़ाता है। मुझे यह एक बिंदु पर काम कर रहा है, लेकिन मैंने जो किया वह स्पष्ट रूप से एक हैक था जिसे मैं यहां पूछना चाहता था कि यह कैसे idiomatically संभाला जाएगा।

एक idiomatically इंटीग्रल -> फ्रैक्शनल/वास्तविक रूपांतरण एच में आवश्यक कैसे संभालता है? मैंने कई चीजें पढ़ी लेकिन कुछ भी स्पष्ट और साफ नहीं लग रहा था।

sigma :: (Ord a, Num b) => (a -> b) -> a -> (a -> a) -> a -> b 
sigma f a next b = iter a 0 
    where 
    iter current acc | current > b = acc 
        | otherwise = iter (next current) (acc + f current) 

simpsonIntegral f a b n = 1.0 * (h/3) * (sigma simTerm 0 (1+) n) 
    where 
    h = (b - a)/n 
    simTerm k = (yk k) * term 
     where 
     yk k = f (a + h * k) 
     term = 
      case k of 
      0 -> 1 
      1 -> 1 
      otherwise -> if odd k then 4 else 2 

उत्तर

3

न्याय के जवाब पर का पालन करें: यदि आप जहां fromIntegral रों, निम्नलिखित compiles डाल करने को लेकर उत्सुक हैं:

simpsonIntegral :: (Integral a, Fractional b) => (b -> b) -> a -> a -> a -> b 
simpsonIntegral f a b n = 1.0 * (h/3) * (sigma simTerm 0 (1+) n) 
    where 
    h = fromIntegral (b - a)/fromIntegral n 
    simTerm k = (yk k) * term 
     where 
     yk k = f (fromIntegral a + h * fromIntegral k) 
     term = 
      case k of 
      0 -> 1 
      1 -> 1 
      otherwise -> if odd k then 4 else 2 

और काम करने के लिए लगता है:

*Main> simpsonIntegral (^3) 0 1 100 
0.2533333233333334 
*Main> simpsonIntegral (^3) 0 1 1000 
0.2503333333323334 
6
fromIntegral :: (Integral a, Num b) => a -> b 

r = fromIntegral i 
+0

इंटेग्रल से प्रश्न। मैं कोशिश कर रहा था लेकिन ट्रैविस के जवाब के सही स्थानों पर नहीं और मैंने सोचा कि यह काम नहीं कर रहा है क्योंकि इस http://www.haskell.org/tutorial/numbers.html num के अनुसार एक डिवीजन ऑपरेटर प्रदान नहीं करता है। रिटर्न प्रकार और ghc infers पर इंटेग्रल पॉलिमॉर्फिक से है कि मैं एक फ्रैक्शनल रिटर्न प्रकार चाहते हैं? – asm

+0

हां, 'इंटेग्रल' से इसके रिटर्न प्रकार 'बी' में पॉलिमॉर्फिक है, उस' बी '(रिटर्न टाइप) में किसी भी प्रकार का डेटा प्रकार होने की अनुमति है जो' न्यूम टाइप क्लास 'का सदस्य है। जबकि 'न्यू' टाइप क्लास डिवीजन प्रदान नहीं करता है, उस प्रकार के वर्ग के सदस्य कुछ डेटा प्रकार डिवीजन प्रदान करते हैं, जैसे कि 'डबल'। – yfeldblum

1

समस्या यह है कि फ़ंक्शन "विषम" अपेक्षा करता है कि यह एक अभिन्न प्रकार होने का तर्क है। संकलक तब अनुमान लगाता है कि आपका चर "के" इंटीग्रल प्रकार का है। लेकिन ऑपरेशन का उपयोग करके "/", कंपाइलर "के" को फ्रैक्शनल प्रकार का भी इस्तेमाल करता है। समाधान पूर्णांक के लिए जहां यह वास्तव में आवश्यक है "कश्मीर" में परिवर्तित करने के रूप में सरल किया जा सकता है:

if odd (round k) then 4 else 2 

आप हास्केल में संख्यात्मक रूपांतरण के बारे में अधिक जानने के लिए चाहते हैं, जाँच Converting_numbers

एक तरफ ध्यान दें के रूप में, यहाँ एक और है अपना सिग्मा फ़ंक्शन लिखने का तरीका:

sigma f a next b = sum $ map f $ takeWhile (<= b) $ iterate next a 
संबंधित मुद्दे