From f5d1d49e3320e3f5407f77f232e4dcb1bb5ba380 Mon Sep 17 00:00:00 2001 From: Jan Sucan Date: Sun, 3 Sep 2023 11:57:33 +0200 Subject: 8_c_2: Add solution --- ch08/Module_8_c_1.hs | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 ch08/Module_8_c_1.hs (limited to 'ch08/Module_8_c_1.hs') diff --git a/ch08/Module_8_c_1.hs b/ch08/Module_8_c_1.hs new file mode 100644 index 0000000..d8a2588 --- /dev/null +++ b/ch08/Module_8_c_1.hs @@ -0,0 +1,81 @@ +-- Write a version of globToRegex that uses the type signature earlier. + +module Module_8_c_1 (GlobError, globToRegex) where + +{-- 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]\\+$" -- cgit v1.2.3