diff options
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | ch08/8_c_1.hs | 79 |
2 files changed, 80 insertions, 1 deletions
@@ -116,7 +116,7 @@ of a group is in bold italics. | **_8_b_1_** | yes, in 8_a_2 | 210 | | | 8_b_2 | yes | | | | 8_b_3 | yes | | | -| **_8_c_1_** | | 211 | | +| **_8_c_1_** | yes | 211 | | | 8_c_2 | | | | | **_8_d_1_** | | 212 | | | **_9_a_1_** | | 221 | 9. I/O case study: a library for searching the filesystem | diff --git a/ch08/8_c_1.hs b/ch08/8_c_1.hs new file mode 100644 index 0000000..ce80ade --- /dev/null +++ b/ch08/8_c_1.hs @@ -0,0 +1,79 @@ +-- Write a version of globToRegex that uses the type signature earlier. + +{-- From examples/examples/ch08/GlobRegex.hs modified according to the assignment --} +import Text.Regex.Posix ((=~)) + +type GlobError = String + +globToRegex :: String -> Either GlobError String + +globToRegex cs = propagateError regex + where regex = globToRegex' cs + propagateError (Left e) = Left e + propagateError (Right s) = Right ('^' : s ++ "$") + +globToRegex' :: String -> Either GlobError String +globToRegex' "" = Right "" + +globToRegex' ('*':cs) = propagateError regex + where regex = globToRegex' cs + propagateError (Left e) = Left e + propagateError (Right s) = Right (".*" ++ s) + +globToRegex' ('?':cs) = propagateError regex + where regex = globToRegex' cs + propagateError (Left e) = Left e + propagateError (Right s) = Right ("." ++ s) + +globToRegex' ('[':'!':c:cs) = propagateError charCls + where charCls = charClass cs + propagateError (Left e) = Left e + propagateError (Right s) = Right ("[^" ++ c : s) + +globToRegex' ('[':c:cs) = propagateError charCls + where charCls = charClass cs + propagateError (Left e) = Left e + propagateError (Right s) = Right ('[' : c : s) + +globToRegex' ('[':_) = Left "unterminated character class" + +globToRegex' (c:cs) = propagateError regex + where regex = globToRegex' cs + propagateError (Left e) = Left e + propagateError (Right s) = Right ((escape c) ++ s) + + +escape :: Char -> String +escape c | c `elem` regexChars = '\\' : [c] + | otherwise = [c] + where regexChars = "\\+()^$.{}]|" + + +charClass :: String -> Either GlobError String + +charClass (']':cs) = propagateError regex + where regex = globToRegex' cs + propagateError (Left e) = Left e + propagateError (Right s) = Right (']' : s) + +charClass (c:cs) = propagateError charCls + where charCls = charClass cs + propagateError (Left e) = Left e + propagateError (Right s) = Right (c : s) + +charClass [] = Left "unterminated character class" +{-- End of code from examples --} + + +-- ghci> :l 8_c_1.hs +-- [1 of 1] Compiling Main ( 8_c_1.hs, interpreted ) +-- Ok, one module loaded. + +-- ghci> globToRegex "[" +-- Left "unterminated character class" + +-- ghci> globToRegex "[]" +-- Left "unterminated character class" + +-- ghci> globToRegex "a?b*c[!DE][FG]+" +-- Right "^a.b.*c[^DE][FG]\\+$" |
