mirror of
https://github.com/iritmaximus/haskell.git
synced 2026-10-12 19:13:39 +03:00
Move Set 11b Ex 5 to Set 13b
This commit is contained in:
@@ -82,34 +82,6 @@ doubleCall op = todo
|
||||
compose :: (a -> IO b) -> (c -> IO a) -> c -> IO b
|
||||
compose op1 op2 c = todo
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Ex 5: Implement the operation mkCounter that produces the IO operations
|
||||
-- inc :: IO () and get :: IO Int. These operations should work like this:
|
||||
--
|
||||
-- get returns the number of times inc has been called
|
||||
--
|
||||
-- In other words, a simple stateful counter. Use an IORef to store the count.
|
||||
--
|
||||
-- Note: this is an IO operation that produces two IO operations. Thus
|
||||
-- the type of mkCounter is IO (IO (), IO Int).
|
||||
--
|
||||
-- This exercise is tricky. Feel free to leave it until later.
|
||||
--
|
||||
-- An example of how mkCounter works in GHCi:
|
||||
--
|
||||
-- *Set11b> (inc,get) <- mkCounter
|
||||
-- *Set11b> inc
|
||||
-- *Set11b> inc
|
||||
-- *Set11b> get
|
||||
-- 2
|
||||
-- *Set11b> inc
|
||||
-- *Set11b> inc
|
||||
-- *Set11b> get
|
||||
-- 4
|
||||
|
||||
mkCounter :: IO (IO (), IO Int)
|
||||
mkCounter = todo
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Ex 6: Reading lines from a file. The module System.IO defines
|
||||
-- operations for Handles, which represent open files that can be read
|
||||
|
||||
@@ -23,7 +23,6 @@ tests = [(1,"appendAll",[ex1])
|
||||
,(2,"swapIORefs",[ex2])
|
||||
,(3,"doubleCall",[ex3_doubleCall, ex3_doubleCall_2])
|
||||
,(4,"composeIO",[ex4_composeIO_1, ex4_composeIO_2])
|
||||
,(5,"mkCounter",[ex5_mkCounter])
|
||||
,(6,"hFetchLines",[ex6])
|
||||
,(7,"hSelectLines",[ex7_hSelectLines])
|
||||
,(8,"interact'",[ex8_interact_terminates, ex8_interact_example, ex8_interact_loop])]
|
||||
@@ -80,15 +79,6 @@ ex4_composeIO_2 =
|
||||
($ compose (return . (*2)) (return . (+1)) i) . withNoInput $
|
||||
checkResult (?== (i+1)*2)
|
||||
|
||||
|
||||
ex5_mkCounter = forAllBlind (choose (0,20)) $ \n ->
|
||||
counterexample "(inc,get) <- mkCounter" $
|
||||
counterexample (" Called inc "++show n++" times, then called get") $
|
||||
monadicIO $ do m <- run $ do (i,g) <- mkCounter
|
||||
replicateM_ n i
|
||||
g
|
||||
stop_ $ m ?== n
|
||||
|
||||
ex6 = forAllBlind (listOf1 word) $ \lines ->
|
||||
counterexample ("Contents of handle h:\n"++unlines lines) $
|
||||
counterexample "hFetchLines h" $
|
||||
|
||||
@@ -5,6 +5,7 @@ import Mooc.Todo
|
||||
import Control.Monad
|
||||
import Control.Monad.Trans.State
|
||||
import Data.Char
|
||||
import Data.IORef
|
||||
import Data.List
|
||||
|
||||
|
||||
@@ -323,3 +324,31 @@ instance Monad SL where
|
||||
-- implement return and >>=
|
||||
return = todo
|
||||
(>>=) = todo
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Ex 9: Implement the operation mkCounter that produces the IO operations
|
||||
-- inc :: IO () and get :: IO Int. These operations should work like this:
|
||||
--
|
||||
-- get returns the number of times inc has been called
|
||||
--
|
||||
-- In other words, a simple stateful counter. Use an IORef to store the count.
|
||||
--
|
||||
-- Note: this is an IO operation that produces two IO operations. Thus
|
||||
-- the type of mkCounter is IO (IO (), IO Int).
|
||||
--
|
||||
-- This exercise is tricky. Feel free to leave it until later.
|
||||
--
|
||||
-- An example of how mkCounter works in GHCi:
|
||||
--
|
||||
-- *Set11b> (inc,get) <- mkCounter
|
||||
-- *Set11b> inc
|
||||
-- *Set11b> inc
|
||||
-- *Set11b> get
|
||||
-- 2
|
||||
-- *Set11b> inc
|
||||
-- *Set11b> inc
|
||||
-- *Set11b> get
|
||||
-- 4
|
||||
|
||||
mkCounter :: IO (IO (), IO Int)
|
||||
mkCounter = todo
|
||||
|
||||
+12
-1
@@ -11,9 +11,11 @@ import qualified Data.Bits
|
||||
import Data.Char
|
||||
import Data.Either
|
||||
import Data.Function
|
||||
import Data.IORef
|
||||
import Data.List
|
||||
import qualified Data.Map as Map
|
||||
import Test.QuickCheck hiding (Result,Failure)
|
||||
import Test.QuickCheck.Monadic
|
||||
|
||||
import Examples.Bank
|
||||
import Set13b hiding (perhapsIncrement,sumBounded,sumNotTwice)
|
||||
@@ -28,7 +30,8 @@ tests = [(1,"ifM",[ex1_maybe, ex1_state])
|
||||
,(5,"allSums", [ex5_bits])
|
||||
,(6,"foldM", [ex6_sumBounded_ok, ex6_sumBounded_fail, ex6_sumNotTwice])
|
||||
,(7,"Monad Result", [ex7])
|
||||
,(8,"Monad SL", [ex8_fmap_1, ex8_fmap_2, ex8_1, ex8_2, ex8_stress])]
|
||||
,(8,"Monad SL", [ex8_fmap_1, ex8_fmap_2, ex8_1, ex8_2, ex8_stress])
|
||||
,(9,"mkCounter",[ex9_mkCounter])]
|
||||
|
||||
-- -- -- -- -- -- --
|
||||
|
||||
@@ -268,3 +271,11 @@ ex8_stress =
|
||||
(incs,msgs) = partitionEithers ops
|
||||
state = sum incs
|
||||
in counterexample desc $ runSL op 0 ?== ((),state,msgs)
|
||||
|
||||
ex9_mkCounter = forAllBlind (choose (0,20)) $ \n ->
|
||||
counterexample "(inc,get) <- mkCounter" $
|
||||
counterexample (" Called inc "++show n++" times, then called get") $
|
||||
monadicIO $ do m <- run $ do (i,g) <- mkCounter
|
||||
replicateM_ n i
|
||||
g
|
||||
stop_ $ m ?== n
|
||||
|
||||
Reference in New Issue
Block a user