2012-06-13 22 views
10

quiero leer un archivo entero en una cadena y luego usar la función lines para obtener las líneas de la cadena. Estoy tratando de hacerlo con estas líneas de código:Haskell leer las líneas de archivo

main = do 
    args <- getArgs 
    content <- readFile (args !! 0) 
    linesOfFiles <- lines content 

Pero yo estoy recibiendo el siguiente error al compilar anuncio se produce un error:

Couldn't match expected type `IO t0' with actual type `[String]' 
In the return type of a call of `lines' 
In a stmt of a 'do' block: linesOfFiles <- lines content 

pensé uniendo el resultado de readFile a contenido será String DataType, ¿por qué no?

Respuesta

30

Pensé vinculando el resultado de readFile al contenido será un String DataType, ¿por qué no?

De hecho, de eso no se queja el compilador. Veamos el código:

main = do 
    args <- getArgs 
    content <- readFile (args !! 0) 

Ahora content es, según se desee, una llanura String. Y luego lines content es un [String]. Pero usted está utilizando la unión en la línea siguiente

linesOfFiles <- lines content 

en un bloque de do-IO() monádico. Por lo que el compilador espera una expresión de tipo IO something en el lado derecho de la <-, pero que encuentra un [String].

Desde el cómputo lines content no implica ningún IO, debe unirse a su resultado con un let vinculante en lugar de la unión monádico,

let linesOfFiles = lines content 

es la línea que necesita allí.

+0

Además, comparar esto con el tipo de getArgs y readFile, para lo completo. –

+0

¿Cómo funciona esta solución? No puede pasar 'content' a' lines' porque el tipo de 'lines' es' String -> [String] 'y el tipo de' content' es 'IO String' – imkendal

+1

@kjh No,' content' es 'String'. El tipo de 'readFile (args !! 0)' es 'IO String', y vinculamos' content' al "resultado" de esa acción 'IO'. El constructo 'do {a <- acción; cosas; } 'desúbals en' action >> = \ a -> stuff', si 'action' tiene type' IO t', entonces 'a' tiene type' t'. –

Cuestiones relacionadas