1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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, ...}]
|