Difference between revisions of "Cookbook/Files"

From HaskellWiki
Jump to navigation Jump to search
(→‎Writing a filter: Describe interact in words)
m (Fixed broken links)
 
Line 53: Line 53:
   
 
== Writing a filter ==
 
== Writing a filter ==
Using [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:interact interact], you can easily do things with stdin and stdout. <hask>interact</hask> takes a function from <hask>string</hask> to <hask>string</hask> and applies it lazily to the input from stdin, writing the output to stdout.
+
Using [http://haskell.org/ghc/docs/latest/html/libraries/base-4.12.0.0/Prelude.html#v:interact interact], you can easily do things with stdin and stdout. <hask>interact</hask> takes a function from <hask>string</hask> to <hask>string</hask> and applies it lazily to the input from stdin, writing the output to stdout.
   
 
A program to sum up numbers:
 
A program to sum up numbers:

Latest revision as of 21:08, 6 January 2019

Reading from a file

The System.IO library contains the functions needed for file IO. The program below displays the contents of the file c:\test.txt.

import System.IO

main = do
  h <- openFile "c:\\test.txt" ReadMode
  contents <- hGetContents h
  putStrLn contents

Note: It is important never to call hClose on a file-handle which has had hGetContents run on it already. The file handle is in a semi-closed state, and will be closed when the resulting string is garbage collected. Closing it manually may result in a random truncation of the input.

The same program, with some higher-level functions:

main = do
  contents <- readFile "c:\\test.txt"
  putStrLn contents

Writing to a file

The following program writes the first 100 squares to a file:

-- generate a list of squares with length 'num' in string-format.
numbers num = unlines $ take num $ map (show . \x -> x*x) [1..]

main = do
  writeFile "test.txt" (numbers 100)
  putStrLn "successfully written"

This will override the old contents of the file, or create a new file if the file doesn't exist yet. If you want to append to a file, you can use appendFile.

Creating a temporary file

TODO: abstract via 'withTempFile', handle exception

import System.IO
import System.Directory

main = do
  tmpDir <- getTemporaryDirectory
  (tmpFile, h) <- openTempFile tmpDir "foo"
  hPutStr h "Hello world"
  hClose h
  removeFile tmpFile

Writing a filter

Using interact, you can easily do things with stdin and stdout. interact takes a function from string to string and applies it lazily to the input from stdin, writing the output to stdout.

A program to sum up numbers:

main = interact $ show . sum . map read . lines

A program that adds line numbers to each line:

main = interact numberLines
numberLines = unlines . zipWith combine [1..] . lines
 where combine lineNumber text = concat [show lineNumber, " ", text]

Logging to a file

TODO