diff options
| author | Jan Sucan <jan@jansucan.com> | 2023-09-27 15:59:19 +0200 |
|---|---|---|
| committer | Jan Sucan <jan@jansucan.com> | 2023-09-27 15:59:19 +0200 |
| commit | 1bb8a1fb9a13840f96fd395093ae1a8694917ac3 (patch) | |
| tree | aa8a68a308c7278507b93a74df8179202a0cd7a8 /ch09 | |
| parent | 5d47dc25454d0e2e9472aedd7b66099821e6658c (diff) | |
9_b_4: Add solution
Diffstat (limited to 'ch09')
| -rw-r--r-- | ch09/9_b_4.hs | 94 | ||||
| -rw-r--r-- | ch09/ControlledVisit.hs | 1 | ||||
| -rw-r--r-- | ch09/Module_9_b_3.hs (renamed from ch09/9_b_3.hs) | 16 | ||||
| -rw-r--r-- | ch09/test-9_b_4/A.c | bin | 0 -> 1 bytes | |||
| -rw-r--r-- | ch09/test-9_b_4/B.c | bin | 0 -> 2 bytes | |||
| -rw-r--r-- | ch09/test-9_b_4/C.c | bin | 0 -> 3 bytes | |||
| -rw-r--r-- | ch09/test-9_b_4/D.hs | bin | 0 -> 4 bytes | |||
| -rw-r--r-- | ch09/test-9_b_4/E.hs | bin | 0 -> 5 bytes | |||
| -rw-r--r-- | ch09/test-9_b_4/F.hs | bin | 0 -> 6 bytes |
9 files changed, 102 insertions, 9 deletions
diff --git a/ch09/9_b_4.hs b/ch09/9_b_4.hs new file mode 100644 index 0000000..b771271 --- /dev/null +++ b/ch09/9_b_4.hs @@ -0,0 +1,94 @@ +-- Write a wrapper for 'traverse' that lets you control traversal using one +-- predicate and filter results using another. + +-- From the assignment it's not completely clear what controlling traversal +-- means. +-- +-- Let's assume that it means visiting files for which the control predicate is +-- true first. + +import ControlledVisit (traverse', Info(..)) +-- Use predicates for the new Info type from the previous exercise +import Module_9_b_3 + +import Data.List +import System.FilePath (takeExtension) + +traverseWrapper :: (Info -> Bool) -> (Info -> Bool) -> FilePath -> IO [Info] +traverseWrapper orderP filterP path = do + res <- traverse' (order orderP) path + return (filterResults filterP res) + +compareInfos :: (Info -> Bool) -> Info -> Info -> Ordering +compareInfos p infoA infoB = if a && (not b) + then LT -- "greater" Info should appear in the sorted list first + else if (not a) && b + then GT + else EQ + where a = p infoA + b = p infoB + +order :: (Info -> Bool) -> ([Info] -> [Info]) +order p = sortBy (compareInfos p) + +filterResults :: (Info -> Bool) -> [Info] -> [Info] +filterResults p infos = filter p infos + + +-- > ls -l +-- total 24 +-- -rw-r--r-- 1 jan users 1 Sep 27 15:28 A.c +-- -rw-r--r-- 1 jan users 2 Sep 27 15:28 B.c +-- -rw-r--r-- 1 jan users 3 Sep 27 15:28 C.c +-- -rw-r--r-- 1 jan users 4 Sep 27 15:28 D.hs +-- -rw-r--r-- 1 jan users 5 Sep 27 15:28 E.hs +-- -rw-r--r-- 1 jan users 6 Sep 27 15:28 F.hs + +idTest :: Info -> Bool +idTest _ = True + +-- ghci> :l 9_b_4.hs +-- [1 of 3] Compiling ControlledVisit ( ControlledVisit.hs, interpreted ) +-- [2 of 3] Compiling Module_9_b_3 ( Module_9_b_3.hs, interpreted ) +-- [3 of 3] Compiling Main ( 9_b_4.hs, interpreted ) +-- Ok, three modules loaded. + +sizeTest1 = infoSize `lesserP` (Just 3) + +sizeTest2 = infoSize `greaterP` (Just 2) + +nameTest = (liftPath takeExtension) `equalP` ".c" + +complexTest1 = (infoSize `lesserP` (Just 4)) `andP` ((liftPath takeExtension) `equalP` ".hs") + +complexTest2 = (infoSize `greaterP` (Just 4)) `andP` (infoSize `lesserP` (Just 6)) + `andP` ((liftPath takeExtension) `equalP` ".hs") + +-- ghci> traverseWrapper idTest idTest "test-9_b_4/" +-- [Info {infoPath = "test-9_b_4/", ..., infoSize = Nothing, ...}, +-- Info {infoPath = "test-9_b_4/F.hs", ..., infoSize = Just 6, ...}, +-- Info {infoPath = "test-9_b_4/A.c", ..., infoSize = Just 1, ...}, +-- Info {infoPath = "test-9_b_4/B.c", ..., infoSize = Just 2, ...}, +-- Info {infoPath = "test-9_b_4/D.hs", ..., infoSize = Just 4, ...}, +-- Info {infoPath = "test-9_b_4/E.hs", ..., infoSize = Just 5, ...}, +-- Info {infoPath = "test-9_b_4/C.c", ..., infoSize = Just 3, ...}] + +-- ghci> traverseWrapper sizeTest1 idTest "test-9_b_4/" +-- [Info {infoPath = "test-9_b_4/", ..., infoSize = Nothing, ...}, +-- Info {infoPath = "test-9_b_4/A.c", ..., infoSize = Just 1, ...}, +-- Info {infoPath = "test-9_b_4/B.c", ..., infoSize = Just 2, ...}, +-- Info {infoPath = "test-9_b_4/F.hs", ..., infoSize = Just 6, ...}, +-- Info {infoPath = "test-9_b_4/D.hs", ..., infoSize = Just 4, ...}, +-- Info {infoPath = "test-9_b_4/E.hs", ..., infoSize = Just 5, ...}, +-- Info {infoPath = "test-9_b_4/C.c", ..., infoSize = Just 3, ...}] + +-- ghci> traverseWrapper sizeTest2 nameTest "test-9_b_4/" +-- [Info {infoPath = "test-9_b_4/C.c", ..., infoSize = Just 3, ...}, +-- Info {infoPath = "test-9_b_4/A.c", ..., infoSize = Just 1, ...}, +-- Info {infoPath = "test-9_b_4/B.c", ..., infoSize = Just 2, ...}] + +-- ghci> traverseWrapper idTest complexTest1 "test-9_b_4/" +-- [] + +-- ghci> traverseWrapper idTest complexTest2 "test-9_b_4/" +-- [Info {infoPath = "test-9_b_4/E.hs", ..., infoSize = Just 5, ...}] diff --git a/ch09/ControlledVisit.hs b/ch09/ControlledVisit.hs index 9793cdd..52f4e9a 100644 --- a/ch09/ControlledVisit.hs +++ b/ch09/ControlledVisit.hs @@ -4,6 +4,7 @@ module ControlledVisit , getInfo
, getUsefulContents
, isDirectory
+ , traverse'
) where
import Control.Exception
diff --git a/ch09/9_b_3.hs b/ch09/Module_9_b_3.hs index 882f7db..ce38717 100644 --- a/ch09/9_b_3.hs +++ b/ch09/Module_9_b_3.hs @@ -1,18 +1,15 @@ -- Take the predicates and combinators from "Gluing predicates together" on page -- 224 and make them work with our new Info type. +module Module_9_b_3 where + {-- From examples/examples/ch09/BetterPredicate.hs modified according to the assignment --} import Data.Time (UTCTime(..)) import System.Directory (Permissions(..)) import System.FilePath (takeExtension) +import ControlledVisit (Info(..)) -data Info = Info { - infoPath :: FilePath - , infoPerms :: Maybe Permissions - , infoSize :: Maybe Integer - , infoModTime :: Maybe UTCTime - } deriving (Eq, Ord, Show) type InfoF a = Info -> a @@ -51,9 +48,10 @@ myTest2 = (liftPath takeExtension `equalP` ".cpp") `andP` (infoSize `greaterP` (Just 131072)) {-- End of code from examples --} --- ghci> :l 9_b_3.hs --- [1 of 1] Compiling Main ( 9_b_3.hs, interpreted ) --- Ok, one module loaded. +-- ghci> :l Module_9_b_3.hs +-- [1 of 2] Compiling ControlledVisit ( ControlledVisit.hs, interpreted ) +-- [2 of 2] Compiling Module_9_b_3 ( Module_9_b_3.hs, interpreted ) +-- Ok, two modules loaded. -- ghci> infoA = Info "asdf.cpp" Nothing (Just 131072) Nothing -- ghci> myTest2 infoA diff --git a/ch09/test-9_b_4/A.c b/ch09/test-9_b_4/A.c Binary files differnew file mode 100644 index 0000000..f76dd23 --- /dev/null +++ b/ch09/test-9_b_4/A.c diff --git a/ch09/test-9_b_4/B.c b/ch09/test-9_b_4/B.c Binary files differnew file mode 100644 index 0000000..09f370e --- /dev/null +++ b/ch09/test-9_b_4/B.c diff --git a/ch09/test-9_b_4/C.c b/ch09/test-9_b_4/C.c Binary files differnew file mode 100644 index 0000000..4227ca4 --- /dev/null +++ b/ch09/test-9_b_4/C.c diff --git a/ch09/test-9_b_4/D.hs b/ch09/test-9_b_4/D.hs Binary files differnew file mode 100644 index 0000000..593f470 --- /dev/null +++ b/ch09/test-9_b_4/D.hs diff --git a/ch09/test-9_b_4/E.hs b/ch09/test-9_b_4/E.hs Binary files differnew file mode 100644 index 0000000..40b450d --- /dev/null +++ b/ch09/test-9_b_4/E.hs diff --git a/ch09/test-9_b_4/F.hs b/ch09/test-9_b_4/F.hs Binary files differnew file mode 100644 index 0000000..ab2c684 --- /dev/null +++ b/ch09/test-9_b_4/F.hs |
