Difference between revisions of "PFP Laboratory 7"

From Marek Běhálek Wiki
Jump to navigation Jump to search
(Created page with "== Working with files - monad IO == * Create a program that reads a file and number it's lines and writes it on the screen. <div> For the solution look at: </translate>[https...")
 
 
(5 intermediate revisions by the same user not shown)
Line 2: Line 2:
 
* Create a program that reads a file and number it's lines and writes it on the screen.
 
* Create a program that reads a file and number it's lines and writes it on the screen.
 
<div>
 
<div>
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>]
+
For the solution look at: [https://hackage.haskell.org/package/base-4.16.0.0/docs/System-IO.html#v:openFile <code>openFile :: FilePath -> IOMode -> IO Handle</code>]
  
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>]
+
The <code>Handle</code> can used to work with a file. The function to read a content:[https://hackage.haskell.org/package/base-4.16.0.0/docs/System-IO.html#v:hGetContents <code>hGetContents :: Handle -> IO String</code>]
  
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>]
+
At the end, you should close the opened file handle: [https://hackage.haskell.org/package/base-4.16.0.0/docs/System-IO.html#v:hClose <code>hClose :: Handle -> IO ()</code>]
  
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>]
+
Alternatively you can use : [https://hackage.haskell.org/package/base-4.16.0.0/docs/Prelude.html#v:readFile <code>readFile :: FilePath -> IO String</code>]
 
</div>
 
</div>
  
Line 36: Line 36:
 
</div>
 
</div>
 
<div style="clear:both"></div>
 
<div style="clear:both"></div>
 +
 +
== Computing PI ==
 +
* Create a program, that computes aproximation of PI using random numbers - [https://towardsdatascience.com/estimate-pi-using-random-numbers-8b13a7e8c791 Idea].
 +
* The number of steps will be defined as program's argument.
 +
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 +
<syntaxhighlight lang="Haskell">
 +
module Main (main) where
 +
import System.Random
 +
import System.Environment
 +
 +
myCycle :: Integer -> Integer -> IO Integer
 +
myCycle i c
 +
  | i == 0 = return c
 +
  | otherwise = do
 +
    x <- randomRIO (0, 1.0) :: IO Double
 +
    y <- randomRIO (0, 1.0) :: IO Double
 +
    myCycle (i-1) (if sqrt (x*x + y*y) <= 1 then c+1 else c)
 +
 +
main :: IO ()
 +
main = do
 +
    [arg] <- getArgs
 +
    let number = read arg::Integer
 +
    inside <- myCycle number 0
 +
    let my_pi = (fromIntegral (4*inside) / fromIntegral number) :: Double
 +
    print my_pi
 +
</syntaxhighlight>
 +
</div>
 +
<div style="clear:both"></div>
 +
 +
== Monads ==
 +
* Make following types instances of the type class <code>Monad</code>.
 +
<syntaxhighlight lang="Haskell">
 +
data MyMaybe a = MyJust a | MyNothing
 +
data MyList a = MyList [a]
 +
data MyEither a b = MyLeft a | MyRight b
 +
</syntaxhighlight>

Latest revision as of 11:58, 5 November 2024

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

Computing PI

  • Create a program, that computes aproximation of PI using random numbers - Idea.
  • The number of steps will be defined as program's argument.
module Main (main) where
import System.Random
import System.Environment

myCycle :: Integer -> Integer -> IO Integer
myCycle i c
  | i == 0 = return c
  | otherwise = do 
    x <- randomRIO (0, 1.0) :: IO Double
    y <- randomRIO (0, 1.0) :: IO Double
    myCycle (i-1) (if sqrt (x*x + y*y) <= 1 then c+1 else c)

main :: IO ()
main = do 
    [arg] <- getArgs
    let number = read arg::Integer
    inside <- myCycle number 0
    let my_pi = (fromIntegral (4*inside) / fromIntegral number) :: Double
    print my_pi

Monads

  • Make following types instances of the type class Monad.
data MyMaybe a = MyJust a | MyNothing
data MyList a = MyList [a]
data MyEither a b = MyLeft a | MyRight b