2011-10-18 12 views
12

में सरल शब्द गणना यह मेरा पहला हैकेल कार्यक्रम है! "wordCount" शब्दों की एक सूची में आता है और प्रत्येक उपयोग-असंवेदनशील शब्द के साथ एक ट्यूपल देता है जो इसकी उपयोग गणना के साथ जोड़ा जाता है। कोड पठनीयता या प्रदर्शन पर सुधार के लिए कोई सुझाव?हैकेल

import List; 
import Char; 
uniqueCountIn ns xs = map (\x -> length (filter (==x) xs)) ns 
nubl (xs) = nub (map (map toLower) xs) -- to lowercase 
wordCount ws = zip ns (uniqueCountIn ns ws) 
    where ns = nubl ws 

उत्तर

24

आपके पहले कार्यक्रम पर बधाई!

सफाई के लिए: अर्धविराम खो दें। इसके बजाय नए पदानुक्रमित मॉड्यूल नामों का उपयोग करें (Data.List, Data.Char)। प्रकार हस्ताक्षर जोड़ें। जैसे ही आप फ़ंक्शन संरचना के साथ अधिक सहज महसूस करते हैं, ईटा आपके फ़ंक्शन परिभाषाओं को अनुबंधित करता है (सही तर्क हटाएं)। जैसे

import Data.List (nub) 
import Data.Char (toLower) 

प्रदर्शन के लिए:

nubl :: [String] -> [String] 
nubl = nub . map (map toLower) 

तुम सच में कठोर होना चाहते हैं, स्पष्ट आयात सूचियों का उपयोग एक Data.Map का उपयोग nub और filter के बजाय संघों स्टोर करने के लिए। विशेष रूप से, fromListWith और toList देखें। उन कार्यों का उपयोग करके आप अपने कार्यान्वयन को सरल बना सकते हैं और एक ही समय में प्रदर्शन में सुधार कर सकते हैं।

+0

धन्यवाद, आज रात मैं उन सुझावों के साथ इसे ठीक कर दूंगा। आपने उस कर्म को अर्जित किया :) –

2

कार्यों के प्रकार हस्ताक्षर जोड़ना वास्तव में मदद करेगा।

6

प्रतिक्रिया के लिए अधिक अनुभवी डेवलपर्स से पूछना हमेशा अच्छा होता है। फिर भी आप कुछ छोटे पैमाने पर मुद्दों पर प्रतिक्रिया प्राप्त करने के लिए hlint का उपयोग कर सकते हैं। यह आपको पदानुक्रमित आयात, अनावश्यक संश्लेषण, वैकल्पिक उच्च-आदेश कार्यों आदि के बारे में बताएगा।

फ़ंक्शन के बारे में, nub1। यदि आप पैरामीटर को पूरी तरह से हटाने के लिए लुक्की की सलाह का पालन नहीं करते हैं, तो मैं कम से कम समीकरण के दाईं ओर xs के आसपास कोष्ठक को हटा दूंगा।

+0

मुझे लगता है कि आप दाएं हाथ की बजाय बाईं तरफ थे। –

+0

हाँ, आप सही हैं। – jmg

15

पठनीयता में सुधार करने के तरीकों में से एक मानक कार्यों में उपयोग करने का प्रयास करना है। Hoogle उपकरण दुनिया के बाकी हिस्सों से अलग हास्केल सेट कि से एक है;)

import Data.Char (toLower) 
import Data.List (sort, group) 
import Control.Arrow ((&&&)) 

wordCount :: String -> [(String, Int)] 
wordCount = map (head &&& length) . group . sort . words . map toLower 

संपादित: स्पष्टीकरण: तो तुम मैपिंग की एक श्रृंखला के रूप में यह के बारे में सोच:

  • (map toLower) :: String -> String lowercases पूरे पाठ, मामले असंवेदनशीलता
  • words :: String -> [String] के प्रयोजन के लिए शब्दों में टेक्स्ट का एक हिस्सा विभाजन
  • sort :: Ord a => [a] -> [a] सॉर्ट करता
  • group :: Eq a => [a] -> [[a]] बटोरता किसी सूची में identicial तत्वों, उदाहरण के लिए, group [1,1,2,3,3] ->[[1,1],[2],[3,3]]
  • &&& :: (a -> b) -> (a -> c) -> (a -> (b, c)), डेटा के एक ही टुकड़े पर दो कार्यों लागू होता है तो परिणामों की टपल देता है। उदाहरण के लिए: (head &&& length) ["word","word","word"] ->("word", 3) (वास्तव में &&& एक छोटे से अधिक सामान्य है, लेकिन सरलीकृत व्याख्या इस उदाहरण के लिए काम करता है)

संपादित: या वास्तव में, Hackage पर "मल्टीसेट" पैकेज के लिए देखो।

+3

अमूर्त कार्यात्मक कार्यान्वयन एक शुरुआत के लिए उपयुक्त नहीं है (उदाहरण के लिए '&&&'), बिना किसी स्पष्टीकरण के। -1 – luqui

+2

ठीक है, मुझे स्पष्टीकरण T_T – Phil

+4

बहुत बेहतर जोड़ने दें। मुझे श्रृंखला के क्रम को पसंद है और आपने टाइप हस्ताक्षर शामिल किए हैं ताकि हम देख सकें कि श्रृंखला के माध्यम से डेटा कैसे बदलता है। – luqui