[Haskell-beginners] wrapping text in a multiline string

Chaddaï Fouché chaddai.fouche at gmail.com
Sun Jun 10 14:04:35 CEST 2012


On Fri, Jun 8, 2012 at 1:33 PM, Rico Moorman <rico.moorman at gmail.com> wrote:
>> Or you could just use matchM :
>>
>>>        go text = case RE.matchM regex' text of
>>>           Just (before, match, after) ->
>>>               before ++ replace' match ++ go after
>>>           _ -> text
>>
>> and have match be a string, just like before (since you don't use all
>> the power of MatchText anyway).
>
> Thank you very much for this suggestion. It works correctly. This is
> the final function (for reference):
>
> regexReplace :: String -> (String -> String) -> String -> String
> regexReplace pattern replace text = go text
>    where
>        regex = RE.makeRegexOpts compOpts RE.defaultExecOpt pattern
>        compOpts = RE.compMultiline + RE.compDotAll
>        go text = case RE.matchM regex text of
>            Just (before, match, after) ->
>                before ++ replace match ++ go after
>            _ -> text
>
> It is really interesting that the result of a function can behave like
> this though. I mean that a different structure is returned based on
> the type (inferred/given) within the dependant function, e.g. [String]
> or Bool ...

This is something that's possible with typeclass in Haskell and one of
the way they differ from interfaces in the OO world. The classic
example is the Read typeclass and "read :: (Read a) => String -> a".

> One other thing I saw is that there can be a runtime error using the
> option compUTF8 even if the compNoUTF8Check is set too. I get:
>
> user error (Text.Regex.PCRE.String died: (ReturnCode (-10),"Error in
> Text.Regex.PCRE.Wrap: ReturnCode (-10)"))
>
> which is the error code for bad utf8 (PCRE_ERROR_BADUTF8) according to
> http://www.pcre.org/pcre.txt . Luckily I don't seem to need those
> options (yet). Would there be some way to "catch"/trace/fix those
> error somehow?

Fix I don't know since that's an internal error of the PCRE package or
library but you can catch exceptions though only in the IO monad. In
this particular case there may be an alternative since what fails is
the compilation of the regex itself and makeRegexOpts has an
alternative which handle errors : makeRegexOptsM . In this case
writing your whole replace function in the Maybe monad would probably
be a good idea :

> regexMaybeReplace :: String -> (String -> String) -> String -> Maybe String
> regexMaybeReplace pattern replace text = do
>   let compOpts = RE.compMultiline + RE.compDotAll
>   regex <- RE.makeRegexOpts compOpts RE.defaultExecOpt pattern
>   (before, match, after) <- RE.matchM regex text
>   return $ before ++ replace match ++ regexReplace after
>
> regexReplace  :: String -> (String -> String) -> String -> String
> regexReplace pattern replace text = fromMaybe text (regexMaybeReplace pattern replace text)

Or something like that.

-- 
Jedaï



More information about the Beginners mailing list