putstrln print file haskell words

file - print - Lectura de archivos haskell



print haskell (3)

¡No es un mal comienzo! Lo único que hay que recordar es que la aplicación de función pura debe usar let lugar del enlace <- .

import System.IO import Control.Monad main = do let list = [] handle <- openFile "test.txt" ReadMode contents <- hGetContents handle let singlewords = words contents list = f singlewords print list hClose handle f :: [String] -> [Int] f = map read

Este es el cambio mínimo necesario para que la cosa se compile y ejecute. Estilísticamente, tengo algunos comentarios:

  1. La list enlaces dos veces se ve un poco sombría. Tenga en cuenta que esto no está mutando la list valores, sino que está siguiendo la definición anterior.
  2. Funciones puras en línea mucho más!
  3. Cuando sea posible, es preferible usar readFile a abrir, leer y cerrar un archivo manualmente.

Implementar estos cambios da algo como esto:

main = do contents <- readFile "test.txt" print . map readInt . words $ contents -- alternately, main = print . map readInt . words =<< readFile "test.txt" readInt :: String -> Int readInt = read

Hace poco empecé a aprender Haskell y tengo muchos problemas para entender cómo funciona la lectura del archivo.

Por ejemplo, tengo un archivo de texto "test.txt" Y contiene líneas de números, por ejemplo:

32 4 2 30 300 5

Quiero leer cada línea y luego evaluar cada palabra y agregarlas. Así que estoy tratando de hacer algo como esto hasta ahora:

import System.IO import Control.Monad main = do let list = [] handle <- openFile "test.txt" ReadMode contents <- hGetContents handle singlewords <- (words contents) list <- f singlewords print list hClose handle f :: [String] -> [Int] f = map read

Sé que esto es completamente incorrecto, pero no sé cómo usar la sintaxis correctamente. Cualquier ayuda será apreciada. Además de los enlaces a buenos tutoriales que tienen ejemplos y explicaciones de código, excepto este: http://learnyouahaskell.com/input-and-output Lo he leído completamente


La solución de Daniel Wagner es excelente. Aquí hay otro giro para que pueda obtener más ideas sobre el manejo eficiente de archivos.

{-# LANGUAGE OverloadedStrings #-} import System.IO import qualified Data.ByteString.Lazy.Char8 as B import Control.Applicative import Data.List sumNums :: B.ByteString -> Int sumNums s = foldl'' sumStrs 0 $ B.split '' '' s sumStrs :: Int -> B.ByteString -> Int sumStrs m i = m+int where Just(int,_) = B.readInt i main = do sums <- map sumNums <$> B.lines <$> B.readFile "testy" print sums

Primero, verás el pragma OverloadedStrings. Esto permite usar solo comillas normales para literales de cadena que en realidad son octetos. Usaremos Lazy ByteStrings para procesar el archivo por varias razones. Primero, nos permite transmitir el archivo a través del programa en lugar de forzarlo a la memoria a la vez. Además, los desvíos son más rápidos y más eficientes que las cadenas en general.

Todo lo demás es bastante sencillo. Leemos el archivo en una lista de líneas perezosa y luego asignamos una función de suma a cada una de las líneas. Los <$> son solo accesos directos que nos permiten operar con el valor dentro del functor IO () - si esto es demasiado, me disculpo. Solo quiero decir que cuando lee Archivo no recupera un ByteString, recibe un ByteString envuelto en IO y IO (ByteString). El <$> dice "Oye ''Quiero operar la cosa dentro de la IO y luego envolverla de nuevo.

B.split separa cada línea en números basados ​​en espacios en blanco. (También podríamos usar B.words para esto) La única otra parte interesante es que en sumStrs usamos la deconstrucción / el patrón de comparación para extraer el primer valor del Just que devuelve la función readInt.

Espero que esto haya sido útil. Pregunta si tienes alguna duda.


Para todos los programadores no funcionales que hay por aquí, es un regalo.

unsafePerformIO . readFile $ "file.txt"

Lee un archivo en una cadena

Sin cadena de E / S, solo una cadena normal completamente cargada y lista para usar. Puede que esta no sea la forma correcta, pero funciona y no es necesario cambiar las funciones existentes para que se adapten a la cadena IO

ps no te olvides de importar

import System.IO.Unsafe