diff options
| author | Jan Sucan <jan@jansucan.com> | 2023-09-21 19:55:57 +0200 |
|---|---|---|
| committer | Jan Sucan <jan@jansucan.com> | 2023-09-22 09:57:10 +0200 |
| commit | 5d47dc25454d0e2e9472aedd7b66099821e6658c (patch) | |
| tree | 2a18bbf13a4907eb3e41105e4e9268b69cce876c | |
| parent | 4995d07fdc713077b595a5a09f6cbe427b919bf1 (diff) | |
9_b_3: Add solution
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | ch09/9_b_3.hs | 68 |
2 files changed, 69 insertions, 1 deletions
@@ -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 |
