Beginner help

David Roundy
Wed, 12 Feb 2003 10:12:46 -0500

On Tue, Feb 11, 2003 at 08:17:49PM +0300, antonmuhin ???? wrote:
> Dear Haskellers!
> Another letter from newbie :)
> May you criticize my code for replacing substring in a string cited
> below? Any critics and comments are highly appreciated.
> And some more questions:
> 1. Is there more functional way for text processing? For example,
> intuitively I feel that there is more functional approach for matching
> than one suggested below.type Match = String -> Maybe String

I think the following would be an example of a reasonably nice functional
way of defining part of a regexp matching code.  I think it would be
relatively straightforward to extend it as much as you like.  match here is
the same as your match, and your replace old new s would be my replace
(match old) new s.

Looking back at what I've written, I'm thinking that perhaps the "Match"
type should be a monad, since it seems to have monadic properties, and that
might cut down on the amount of coding.  Most notably, I bet the
matchSequence function would just be the sequence function of a

type Match = String -> Maybe String
-- replace replaces a matched regexp with a constant string.
replace :: Match -> String -> String -> String
replace m repl (c:cs) = case m (c:cs) of
                        Nothing -> c : replace m repl cs
                        Just r -> repl ++ replace m repl r
replace _ _ "" = ""
-- in a regexp a (i.e. the char a)
matchchar :: Char -> Match
matchchar m (c:cs) = if m == c then Just cs else Nothing
-- in a regexp exp1exp2exp3 (i.e. in sequence)
matchSequence :: [Match] -> Match
matchSequence (m:ms) s = m s >>= matchSequence ms
matchSequence [] s = Just s
-- in a regexp abcd
match :: String -> Match
match s = matchSequence $ map matchchar s
-- in a regexp (exp)*
matchStar :: Match -> Match
matchStar m s = case m s of
                Nothing -> Just s
                Just s' -> matchStar m s'
-- in a regexp (exp)+
matchPlus :: Match -> Match
matchPlus m s = case m s of
                Nothing -> Nothing
                Just s' -> matchStar m s'
-- in a regexp (exp1|exp2|exp3)
matchOr :: [Match] -> Match
matchOr (m:ms) s = case m s of
                   Nothing -> matchOr ms s
                   Just s' -> Just s'
matchOr [] s = Nothing
-- In a regexp something like [abc]
matchBrackets :: String -> Match
matchBrackets s = matchOr $ map matchchar s
David Roundy