2011-10-18 15 views
12

Questo è il mio PRIMO programma haskell! "wordCount" contiene un elenco di parole e restituisce una tupla con ogni parola insensibile alle maiuscole e minuscole accoppiata al conteggio dell'utilizzo. Qualche suggerimento per migliorare la leggibilità del codice o le prestazioni?Conteggio parole semplice in haskell

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 

risposta

24

Congratulazioni per il tuo primo programma!

Per pulizia: perdere il punto e virgola. Utilizzare invece i nuovi nomi dei moduli gerarchici (Data.List, Data.Char). Aggiungi le firme del tipo. Man mano che ti senti più a tuo agio con la composizione delle funzioni, eta contrae le definizioni delle tue funzioni (rimuovi gli argomenti più a destra). per esempio.

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

Se vuoi essere veramente rigorosi, utilizzare gli elenchi di importazione espliciti:

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

Per prestazioni: utilizzare un Data.Map per memorizzare le associazioni invece di nub e filter. In particolare, vedere fromListWith e toList. Usando queste funzioni puoi semplificare la tua implementazione e migliorare le prestazioni allo stesso tempo.

+0

Grazie, stasera lo aggiusterò con questi suggerimenti. Hai guadagnato quel karma :) –

2

Aggiungere le firme di tipo delle funzioni sarebbe davvero d'aiuto.

6

È sempre utile chiedere agli sviluppatori più esperti un feedback. Tuttavia è possibile utilizzare hlint per ottenere feedback su alcuni problemi di piccola scala. Ti parlerà di importazioni gerarchiche, parentesi non necessarie, funzioni alternative di ordine superiore, ecc.

Per quanto riguarda la funzione, nub1. Se non segui ancora il consiglio di luqui di rimuovere completamente il parametro, rimuoverò almeno la parentesi attorno allo xs sul lato destro dell'equazione.

+0

Immagino che tu intendessi il lato sinistro invece di quello destro. –

+0

sì, hai ragione. – jmg

15

Uno dei modi per migliorare la leggibilità è cercare di abituarsi alle funzioni standard. Hoogle è uno degli strumenti che imposta Haskell a parte il resto del mondo;)

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 

EDIT: Spiegazione: Così si pensa di esso come una catena di mappature:

  • (map toLower) :: String -> String in minuscolo tutto il testo, ai fini del caso insensibilità
  • words :: String -> [String] divide una parte di testo in parole
  • sort :: Ord a => [a] -> [a] smista
  • group :: Eq a => [a] -> [[a]] raccoglie elementi identicial in una lista, per esempio, group [1,1,2,3,3] ->[[1,1],[2],[3,3]]
  • &&& :: (a -> b) -> (a -> c) -> (a -> (b, c)) vale due funzioni sulla stessa porzione di dati, quindi restituisce tupla dei risultati. Ad esempio: (head &&& length) ["word","word","word"] ->("word", 3) (in realtà &&& è un po 'più generale, ma la spiegazione semplificata funziona per questo esempio)

EDIT: O in realtà, cercare il pacchetto "multiset" su Hackage.

+3

implementazione funzionale astratta non adatta ad un principiante (es. '&&&'), anche senza spiegazione. -1 – luqui

+2

OK, mi permetta di aggiungere la spiegazione T_T – Phil

+4

molto meglio. Mi piace l'ordine della catena e ho incluso le firme dei tipi in modo da poter vedere come i dati si trasformano nel suo percorso attraverso la catena. – luqui

Problemi correlati