2011-10-18 20 views
12

¡Este es mi PRIMER programa haskell! "wordCount" toma una lista de palabras y devuelve una tupla con cada palabra que no distingue entre mayúsculas y minúsculas junto con su recuento de uso. ¿Alguna sugerencia para mejorar la legibilidad o el rendimiento del código?Recuento simple de palabras en 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 

Respuesta

24

¡Felicitaciones en su primer programa!

Para la limpieza: pierda el punto y coma. Use los nuevos nombres de módulo jerárquico en su lugar (Data.List, Data.Char). Agregue firmas de tipo. A medida que se sienta más cómodo con la composición de la función, eta contratará las definiciones de su función (eliminar los argumentos de la derecha). p.ej.

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

Si quieres ser muy rigurosa, utilice las listas de importación explícitos:

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

: Para obtener un rendimiento utilizar un Data.Map para almacenar las asociaciones en lugar de nub y filter. En particular, vea fromListWith y toList. Al usar esas funciones puede simplificar su implementación y mejorar el rendimiento al mismo tiempo.

+0

Gracias, esta noche lo arreglaré con esas sugerencias. Ganaste ese karma :) –

2

Agregar las firmas de tipo de las funciones realmente ayudaría.

6

Siempre es bueno pedir retroalimentación a los desarrolladores más experimentados. Sin embargo, puede usar hlint para obtener comentarios sobre algunos problemas de pequeña escala. Le informará acerca de las importaciones jerárquicas, paréntesis innecesarios, funciones alternativas de orden superior, etc.

En cuanto a la función, nub1. Si no sigue los consejos de luqui para eliminar el parámetro aún, al menos eliminaría el paréntesis alrededor de xs en el lado derecho de la ecuación.

+0

Supongo que te referías al lado izquierdo en lugar de al derecho. –

+0

sí, tienes razón. – jmg

15

Una de las formas de mejorar la legibilidad es intentar acostumbrarse a las funciones estándar. Hoogle es una de las herramientas que establece Haskell aparte del resto del mundo;)

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 

EDITAR: Explicación: ¿Así que pensar en ella como una cadena de asignaciones:

  • (map toLower) :: String -> String minúsculas todo el texto, con el propósito de caso insensibilidad
  • words :: String -> [String] divide un pedazo de texto en palabras
  • sort :: Ord a => [a] -> [a] ordena
  • group :: Eq a => [a] -> [[a]] reúne elementos identicial en una lista, por ejemplo, group [1,1,2,3,3] ->[[1,1],[2],[3,3]]
  • &&& :: (a -> b) -> (a -> c) -> (a -> (b, c)) aplica dos funciones en la misma pieza de datos, a continuación, devuelve la tupla de los resultados. Por ejemplo: (head &&& length) ["word","word","word"] ->("word", 3) (en realidad &&& es un poco más general, pero la explicación simplificada de obras para este ejemplo)

EDITAR: O en realidad, buscar el paquete "conjunto múltiple" en la Hackage.

+3

implementación funcional abstracta no apta para un principiante (por ejemplo, '&&&'), también sin explicación. -1 – luqui

+2

OK, déjame agregar la explicación T_T – Phil

+4

mucho mejor. Me gusta el orden de la cadena y que incluyó firmas de tipo para que podamos ver cómo se transforman los datos en su camino a través de la cadena. – luqui

Cuestiones relacionadas