Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

find and replace with the haskell package Text.RE.TDFA

I'm attempting to replace numbers in a string with twice their value using Haskell's Text.RE.TDFA package. My current approach:

s *=~/ fmap (\x -> show $ 2.0*(read x::Double)) [ed|${doublestring}([0-9]*\.[0-9]*)///${doublestring}|]

Behavior Observed:

  1. When I set s as "xxx1.1xxx", I get the error:
    "regex.hs: Prelude.read: no parse"
  2. If I replace ${doublestring} after /// with a literal number (e.g., 1.1), it works as expected:
    Input: "xxx1.1xxx" → Output: "xxx2.2xxx"

Questions:

  1. Why does the ${doublestring} capture fail during parsing?
  2. What's the proper way to implement the replacement with the TDFA backend?
like image 780
C. Ding Avatar asked Oct 15 '25 16:10

C. Ding


1 Answers

The fuctor acts on the template, not on the variables in the template, indeed:

data SearchReplace re s =
  SearchReplace
    { getSearch   :: !re    -- ^ the RE to match a string to replace
    , getTemplate :: !s     -- ^ the replacement template with ${cap}
                            -- used to identify a capture (by number or
                            -- name if one was given) and '$$' being
                            -- used to escape a single '$'
    }
  deriving (Show)

instance Functor (SearchReplace re) where
  fmap f (SearchReplace re x) = SearchReplace re (f x)

This means that your function is given "${doublestring}" as string. We can confirm this by using a trace:

ghc> "1.1" *=~/ fmap (\x -> show (traceShow x (read x)::Double)) [ed|${doublestring}([0-9]*\.[0-9]*)///${doublestring}|]
""${doublestring}"

We thus never get the value to parse, we get the template to handle.

like image 106
Willem Van Onsem Avatar answered Oct 18 '25 06:10

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!