aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Sucan <jan@jansucan.com>2023-09-21 19:55:57 +0200
committerJan Sucan <jan@jansucan.com>2023-09-22 09:57:10 +0200
commit5d47dc25454d0e2e9472aedd7b66099821e6658c (patch)
tree2a18bbf13a4907eb3e41105e4e9268b69cce876c
parent4995d07fdc713077b595a5a09f6cbe427b919bf1 (diff)
9_b_3: Add solution
-rw-r--r--README.md2
-rw-r--r--ch09/9_b_3.hs68
2 files changed, 69 insertions, 1 deletions
diff --git a/README.md b/README.md
index c5d1a8e..9893c65 100644
--- a/README.md
+++ b/README.md
@@ -127,7 +127,7 @@ are prefixed with 'Module_'.
| **_9_a_1_** | yes | 221 | 9. I/O case study: a library for searching the filesystem |
| **_9_b_1_** | yes | 228 | |
| 9_b_2 | yes | | |
-| 9_b_3 | | | |
+| 9_b_3 | yes | | |
| 9_b_4 | | | |
| **_9_c_1_** | | 232 | |
| 9_c_2 | | | |
diff --git a/ch09/9_b_3.hs b/ch09/9_b_3.hs
new file mode 100644
index 0000000..882f7db
--- /dev/null
+++ b/ch09/9_b_3.hs
@@ -0,0 +1,68 @@
+-- Take the predicates and combinators from "Gluing predicates together" on page
+-- 224 and make them work with our new Info type.
+
+{-- From examples/examples/ch09/BetterPredicate.hs modified according to the assignment --}
+import Data.Time (UTCTime(..))
+import System.Directory (Permissions(..))
+import System.FilePath (takeExtension)
+
+
+data Info = Info {
+ infoPath :: FilePath
+ , infoPerms :: Maybe Permissions
+ , infoSize :: Maybe Integer
+ , infoModTime :: Maybe UTCTime
+ } deriving (Eq, Ord, Show)
+
+type InfoF a = Info -> a
+
+
+equalP :: (Eq a) => InfoF a -> a -> (InfoF Bool)
+equalP f k = (\info -> f info == k)
+
+equalP' :: (Eq a) => (InfoF a) -> a -> (InfoF Bool)
+equalP' f k info = (f info == k)
+
+liftP :: (a -> b -> Bool) -> (InfoF a) -> b -> (InfoF Bool)
+liftP q f k info = f info `q` k
+
+greaterP, lesserP :: (Ord a) => (InfoF a) -> a -> (InfoF Bool)
+greaterP = liftP (>)
+lesserP = liftP (<)
+
+simpleAndP :: (InfoF Bool) -> (InfoF Bool) -> (InfoF Bool)
+simpleAndP f g info = f info && g info
+
+liftP2 :: (a -> b -> Bool) -> (InfoF a) -> (InfoF b) -> (InfoF Bool)
+liftP2 q f g info = f info `q` g info
+
+andP = liftP2 (&&)
+orP = liftP2 (||)
+
+constP :: a -> (InfoF a)
+constP k _ = k
+
+liftP' q f k info = f info `q` constP k info
+
+liftPath :: (FilePath -> a) -> (InfoF a)
+liftPath f info = f (infoPath info)
+
+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> infoA = Info "asdf.cpp" Nothing (Just 131072) Nothing
+-- ghci> myTest2 infoA
+-- False
+
+-- ghci> infoB = Info "asdf.hs" Nothing (Just 131073) Nothing
+-- ghci> myTest2 infoB
+-- False
+
+-- ghci> infoC = Info "asdf.cpp" Nothing (Just 131073) Nothing
+-- ghci> myTest2 infoC
+-- True