Difference between revisions of "FP Laboratory 12"

From Marek Běhálek Wiki
Jump to navigation Jump to search
(Marked this version for translation)
 
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
== Working with files - monad IO ==
+
<translate>
 +
== Working with files - monad IO == <!--T:1-->
 +
* Create a program that reads a file and number it's lines and writes it on the screen.
 +
</translate>
 +
<div>
 +
<translate><!--T:2--> For the solution look at: </translate>[https://hackage.haskell.org/package/base-4.16.0.0/docs/System-IO.html#v:openFile <code>openFile :: FilePath -> IOMode -> IO Handle</code>]
  
* Create a program that reads a file and number it's lines.
+
<translate><!--T:3--> The <code>Handle</code> can used to work with a file. The function to read a content: </translate>[https://hackage.haskell.org/package/base-4.16.0.0/docs/System-IO.html#v:hGetContents <code>hGetContents :: Handle -> IO String</code>]
 +
 
 +
<translate><!--T:4--> At the end, you should close the opened file handle: </translate>[https://hackage.haskell.org/package/base-4.16.0.0/docs/System-IO.html#v:hClose <code>hClose :: Handle -> IO ()</code>]
 +
 
 +
<translate><!--T:5--> Alternatively you can use : </translate>[https://hackage.haskell.org/package/base-4.16.0.0/docs/Prelude.html#v:readFile <code>readFile :: FilePath -> IO String</code>]
 +
</div>
 +
 
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 +
<syntaxhighlight lang="Haskell">
 +
import System.IO
 +
import Control.Exception
 +
 
 +
main = do fromHandle <- opf "Read from: " ReadMode
 +
          contents <- hGetContents fromHandle
 +
          putStr (numberLines contents)
 +
          hClose fromHandle
 +
 
 +
opf :: String -> IOMode -> IO Handle
 +
opf prompt mode = do putStr prompt
 +
                    name <- getLine 
 +
                    catch (openFile name mode )
 +
                          (\e -> do putStr ("Can't open "++name++":"++show (e :: IOException) ++"\n")
 +
                                    opf prompt mode)
 +
 
 +
numberLines::String -> String
 +
numberLines text = let l = lines text
 +
                      numbered = zip [1..] l
 +
                      result = [show x ++".\t"++content++"\n" | (x, content)<-numbered]
 +
                  in concat result
 +
</syntaxhighlight>
 +
</div>
 +
<div style="clear:both"></div>

Latest revision as of 12:47, 6 December 2021

Working with files - monad IO

  • Create a program that reads a file and number it's lines and writes it on the screen.

For the solution look at: openFile :: FilePath -> IOMode -> IO Handle

The Handle can used to work with a file. The function to read a content: hGetContents :: Handle -> IO String

At the end, you should close the opened file handle: hClose :: Handle -> IO ()

Alternatively you can use : readFile :: FilePath -> IO String

import System.IO
import Control.Exception

main = do fromHandle <- opf "Read from: " ReadMode
          contents <- hGetContents fromHandle
          putStr (numberLines contents)
          hClose fromHandle

opf :: String -> IOMode -> IO Handle
opf prompt mode = do putStr prompt
                     name <- getLine  
                     catch (openFile name mode )
                           (\e -> do putStr ("Can't open "++name++":"++show (e :: IOException) ++"\n")
                                     opf prompt mode)

numberLines::String -> String
numberLines text = let l = lines text
                       numbered = zip [1..] l
                       result = [show x ++".\t"++content++"\n" | (x, content)<-numbered]
                   in concat result