2011-07-14 48 views
8

yo soy novato en Haskell, y tengo pregunta: escribo código:Haskell y cadena de longitud

word_list = ["list", "lol", "wordword"] 
check str = if head str == 'l' then tail str else str 
average wl = (length $ concat $ map check wl) `div` length wl 

palabras este código debe eliminar primero el símbolo "L" en cada palabra en la lista de palabras, recibimos concat , obtener la longitud de la cadena de resultados y div en el recuento de palabras.

lo que en este código que debe recibir: 13/3 = 4.333 ... ("listlolwordword" = 15 "istolwordword" = 13) pero yo simplemente recibir 4.

average :: [[Char]] -> Float no funcionan , recibo un error donde mi error? p. lo siento mi Inglés, por favor

Respuesta

12

La función devuelve un lengthInt, y la función div realiza una división entera, en otras palabras, se deja caer la parte fraccionaria. Si quieres un resultado Float, es necesario convertir primero el resultado de length a un Float, a continuación, utilizar (/) para la división en su lugar:

word_list = ["list", "lol", "wordword"] 
check str = if head str == 'l' then tail str else str 
average wl = fromIntegral (length $ concat $ map check wl)/fromIntegral (length wl) 

Mientras estoy en ello, usted debe considerar el uso de coincidencia de patrones en lugar check , por ejemplo:

check ('l':str) = str 
check str = str 

Este estilo es a la vez más fácil de leer y menos propensos a tener errores - por ejemplo, su versión fallará si se les da una cadena vacía.

+0

wow. ¡muchas gracias! sobre la coincidencia de patrones: ¡es increíble! me gusta haskel más todos los días :) –

+1

@user: ten en cuenta que también hay concatMap para que no tengas que hacer 'concat $ map'. –

+1

y me gustaría señalar que un enfoque más claro es probablemente 'suma $ map (longitud de verificación) wl' (aunque la fusión probablemente hace que esto no sea importante) – alternative