2013-02-03 7 views
8

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

वैसे भी, एक समस्या के लिए मैं काम कर रहा हूं मुझे उपयोगकर्ता इनपुट प्राप्त करने की आवश्यकता है। यह

2 
10 
20 

उदाहरण के लिए फॉर्म में आएगा। प्रारूप पहली पंक्ति है जो अनुसरण करने वाली रेखाओं की संख्या कहता है। मेरा पहला विचार था कि मैं पहली पंक्ति पढ़ूंगा, फिर उस लूप को उस समय की संख्या में चलाएं। हालांकि यह हास्केल है! जहां तक ​​मुझे पता है, लूप संभव नहीं हैं।

मेरा अगला विचार यह था कि मैं सूची की अन्य संख्याओं के साथ सूची भरने के लिए इनपुट की पहली पंक्ति का उपयोग करूंगा। मुझे नहीं पता कि मैं यह कैसे करूंगा। मैं यहाँ हूं क्योंकि मुझे यह भी यकीन नहीं है कि मैं इसे समझने के लिए क्या खोजूँगा।

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

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

l n = (-1)^n/(2*(fromIntegral n)+1) 
a m = sum [l n | n <- [0..(m-1)]] 
main = 
    do b <- readLn 
     print (a b) 

(इसके अलावा, मैं अगर वहाँ अन्य सुधार मैं अपने कोड के लिए कर सकता है कर रहे हैं सुनने के लिए प्यार होता है, लेकिन इस विशिष्ट मामले में यह एक प्रतियोगिता संभव पात्रों और उनमें कम में एक समस्या को हल करने के लिए है। मैं यदि अन्य लोग एक ही समस्या के उत्तर की तलाश करने की कोशिश कर रहे हैं तो अधिक विशिष्ट नहीं होना चाहते हैं।)

संपादित करें: हर किसी के उत्तर के लिए धन्यवाद। मुझे अंत में ऐसा कुछ मिला जो व्यवहार करता था कि मैं इसे कैसे चाहता था। मैंने पोस्टरिटी के लिए नीचे दिए गए कोड को रखा है। अफसोस की बात है, भले ही यह उड़ान रंगों के साथ परीक्षण मामलों को पारित कर दिया गया हो, फिर भी उन्होंने जिस वास्तविक डेटा का परीक्षण किया वह अलग था, और वे सभी मुझे बताते हैं कि मुझे "गलत जवाब" मिला है। यह कोड "काम करता है" लेकिन आपको सही उत्तर नहीं मिलता है।

import Control.Monad 
l n = (-1)^n/(2*(fromIntegral n)+1) 
a m = sum [l n | n <- [0..(m-1)]] 
main = 
    do b <- readLn 
     s <- replicateM b readLn 
     mapM_ print [a c | c <- s] 
+0

शायद यह गोल करने में त्रुटि हो रही है? शायद आखिरी मिनट में एक फ्लोट में कनवर्ट करने के बाद तर्कसंगत संख्याओं का उपयोग करने का प्रयास करें: ('डेटा आयात करें। डेटाियो ',' एल :: इंटीजर -> तर्कसंगत', और 'mapM_ (प्रिंट। RealToFrac) ' – luqui

+1

यह प्रकार था पूर्णन त्रुटि। ऐसा करने के बाद भी यह गलत था। मेरी समस्या यह थी कि मैं सटीक था। मैं परिशुद्धता के दशमलव के बाद 16 अंकों की तरह दे रहा था, लेकिन वे केवल 15 अंक चाहते थे। क्या ऐसा करने के लिए कोई हैकेल तरीका है? यह समस्या ऐसी चीज नहीं है जिसे आप असली जिंदगी में चलाएंगे। ज्यादातर कंपनियां कभी भी कम सटीकता के लिए नहीं पूछतीं, और जितनी संभव हो उतनी पात्र (इन भयानक 1 वर्ण परिवर्तनीय नामों के कारण) – maccam912

+0

आपको लूप रखने के लिए केवल एक सूची बनाने की आवश्यकता नहीं है: 'main = do {b <- readLn; replicateM_ b (do {c <- readLn; प्रिंट (एक सी)})} ''। या लूप को सीधे रिकर्सन के साथ कोड किया जा सकता है: 'main = readLn >> = loop'; 'लूप एन | एन <1 = वापसी() | अन्यथा = readLn >> = (प्रिंट ए) >> लूप (एन -1) '। –

उत्तर

10

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

अधिकांश समय, सामान्य सामान्य उद्देश्य लूप पुस्तकालयों में डाल दिए जाते हैं। इस मामले में, मॉड्यूल Control.Monad में, आपको आवश्यक लूप मानक पुस्तकालयों में है। इसे replicateM कहा जाता है। इसमें टाइप हस्ताक्षर Monad m => Int -> m a -> m [a] है। अपने मामले के लिए इस हस्ताक्षर को विशेषज्ञ बनाने के लिए, इसका प्रकार Int -> IO Int -> IO [Int] होगा। पहला तर्क लूप के लिए समय की संख्या है। दूसरा प्रत्येक लूप पर चलाने के लिए आईओ कार्रवाई है। फ़ंक्शन का परिणाम एक आईओ क्रिया है जो इनपुट की सूची उत्पन्न करता है।

इसलिए यदि आप अपने करते ब्लॉक करने के लिए inputs <- replicateM b readLn कहा, ऐसा लगता है कि पहले एक निम्न इनपुट की b लाइनों से मान दायरे में inputs नामक एक सूची जाते थे। फिर आप उन समाधानों पर अपने समाधान फ़ंक्शन को मानचित्र बना सकते हैं।

1

आप readInput n बना सकते हैं जहां n पढ़ने के लिए लाइनों की संख्या है। यह कॉल हर बार n से 1 को घटाकर घटाता है। मैं एक हास्केल नोब भी हूं, इसलिए यह सबसे अच्छा तरीका नहीं हो सकता है। हालांकि, यह अभी भी काम करना चाहिए।

6

कार्ल का समाधान काम करेगा, लेकिन यह कुछ हद तक अपारदर्शी है।आप इसे बाहर लिखना चाहते थे, तो आप इस तरह कुछ कर सकता है:

readLines :: Int -> IO [Int] 
readLines 0 = return [] 
readLines n = do 
    x <- fmap read getLine 
    rest <- readLines (n-1) 
    return $ x : rest 

readSomeNumberOfLines :: IO [Int] 
readSomeNumberOfLines = do 
    n <- fmap read getLine 
    readLines n 

क्या आप readLines के साथ यहाँ क्या कर रहे हैं आप अनिवार्य रूप से स्पष्ट आधार मामला तय कर रहे हैं है (0 चीजों को पढ़ने के लिए, बस एक खाली देना सूची) और रिकर्सिव केस (एन चीजों को पढ़ने के लिए, एक चीज़ पढ़ें, फिर अन्य एन -1 चीजें पढ़ें, फिर उन्हें एक साथ जोड़ दें)। अंत में

import Control.Monad 

-- read n, then sum integers read from the next n lines 
test = do n <- readLn 
      xs <- replicateM n readLn 
      return $ sum xs 

return $ sum xs:

2

मुझे यकीन है कि क्या वास्तव में आपको बस इतना करना है, लेकिन एक पूर्णांक n पढ़ने के लिए और फिर पूर्णांक के रूप में अगले n लाइनों आप की तरह कुछ कर सकते हैं चाहते हैं नहीं कर रहा हूँ बेशक पर्याप्त नहीं है - अगर यह वहां नहीं था तो आपको test के लिए एक स्पष्ट प्रकार हस्ताक्षर की आवश्यकता होगी।

यदि आप इनमें से किसी भी कार्य को नहीं समझते हैं, तो बस hoogle उन्हें।