Beginner help

David Roundy droundy@abridgegame.org
Wed, 12 Feb 2003 10:12:46 -0500


On Tue, Feb 11, 2003 at 08:17:49PM +0300, antonmuhin ???? rambler.ru 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
monad...

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
http://civet.berkeley.edu/droundy/