2013-05-28 11 views
13

मैं हास्केल के लिए नया हूं और interact फ़ंक्शन के साथ समस्या है। - बस स्ट्रिंग है कि यह और अगली पंक्ति में ले जाता है करने के लिए पारित हो जाता है प्रिंटहास्केल इंटरैक्ट फ़ंक्शन

main :: IO() 
main = interact inputLength 

inputLength :: String -> String 
inputLength input = show $ length input 

यह कम्पाइल लेकिन जब चल उत्पादन मुद्रित नहीं करता है: यह मेरा नमूना कार्यक्रम है। जब मैं interact एक और String -> String समारोह इस तरह से पारित:

upperCase :: String -> String 
upperCase input = map toUpper input 

यह ठीक चलाता है और अपरकेस में तर्क के रूप में उम्मीद प्रिंट - तो पहले समारोह के साथ गलत क्या है?

+1

मुझे लगता है कि 'interact' अभी भी एक सुंदर है पाइप के साथ काम करने के लिए कमांड लाइन प्रोग्राम लिखने का तरीका। 'आईओ' के साथ मैं गैर-संगत उपयोगकर्ता-केवल कार्यक्रम लिखने का लुत्फ उठा रहा हूं। – luqui

उत्तर

32

interact :: String -> String एक स्ट्रिंग सभी इनपुट युक्त लेता है और एक स्ट्रिंग सभी उत्पादन युक्त देता है। interact (map toUpper) के साथ दर्ज करने के बाद आउटपुट देखने का कारण यह है कि map toUpper आलसी काम करता है - यह सभी इनपुट ज्ञात होने से पहले आउटपुट देना प्रारंभ कर सकता है। स्ट्रिंग की लंबाई ढूंढना इस तरह नहीं है - किसी भी आउटपुट को उत्पादित करने से पहले पूरी स्ट्रिंग को जानना चाहिए।

आपको या तो यह कहना है कि आप इनपुट में प्रवेश कर रहे हैं (कंसोल में, यह यूनिक्स/मैक सिस्टम पर कंट्रोल-डी है, मुझे विश्वास है कि यह विंडोज़ पर कंट्रोल-जेड है), तो यह आपको देगा लम्बाई। या फिर आप इतना कह कर प्रत्येक लाइन की लंबाई पा सकते हैं:

interact (unlines . map (show . length) . lines) 

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

eachLine :: (String -> String) -> (String -> String) 
eachLine f = unlines . map f . lines 

तो फिर तुम क्या कर सकते हैं:

के बाद लाइनों पर अभिनय इस तरह के एक आम पैटर्न है, मैं एक छोटे से सहायक समारोह परिभाषित करना चाहते

main = interact (eachLine inputLength) 
संबंधित मुद्दे