John | 8 May 06:30 2013
Picon

Incrementation fails

Hello All,

I'm in a big trouble with incrementation of a counter in this code. It
doesn't increment.

Could you please tell me where the problem ist and how can I solve it?

replaceBasedIdx    ::  String  ->  [String]  ->  String  ->  String
replaceBasedIdx    findStr replaceStrList myText = replaceBasedIdxSub
findStr replaceStrList myText 0

replaceBasedIdxSub  ::  String  ->  [String]  ->  String  -> Int -> String
replaceBasedIdxSub findStr replaceStrList myText counter = loop myText
  where
    loop [] = []
    loop myText =
      let (prefix, rest) = splitAt n myText
      in
        if findStr == prefix                                -- found an
occurrence?
        then (replaceStrList !! (counter+1)) ++ loop rest   -- yes: replace
it

        else head myText : loop (tail myText)               -- no: keep
looking
    n = length findStr

Thank you very mutch!

Greetings!
(Continue reading)

Roel van Dijk | 8 May 09:25 2013
Picon

Re: Incrementation fails

Hi John,

Can you tell us what your function is supposed to do? It appears to be some kind of search-and-replace for strings. What is the relationship between 'findStr', 'replaceStrList' and 'myText'?


2013/5/8 John <knowledge1202 <at> gmail.com>
Hello All,

I'm in a big trouble with incrementation of a counter in this code. It
doesn't increment.

Could you please tell me where the problem ist and how can I solve it?

replaceBasedIdx    ::  String  ->  [String]  ->  String  ->  String
replaceBasedIdx    findStr replaceStrList myText = replaceBasedIdxSub
findStr replaceStrList myText 0

replaceBasedIdxSub  ::  String  ->  [String]  ->  String  -> Int -> String
replaceBasedIdxSub findStr replaceStrList myText counter = loop myText
  where
    loop [] = []
    loop myText =
      let (prefix, rest) = splitAt n myText
      in
        if findStr == prefix                                -- found an
occurrence?
        then (replaceStrList !! (counter+1)) ++ loop rest   -- yes: replace
it

        else head myText : loop (tail myText)               -- no: keep
looking
    n = length findStr

Thank you very mutch!

Greetings!

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Roel van Dijk | 8 May 09:39 2013
Picon

Re: Incrementation fails

I stared at the code some more and deduced what I think is the
intented meaning. Occurences of 'findStr' in 'myText' are replaced
with the strings in 'replaceStrList'.

So replaceBasedIdx "X" ["b","d","f"] "aXcXeXg" = "abcdefg"

The reason your counter didn't increment is because it was defined as
an argument to 'replaceBasedIdxSub'. That means its value is fixed
once you evaluate that function. Its value will not change no matter
how many times the inner 'loop' function is evaluated. The solution is
to pass the counter as an argument to said 'loop' function. Now when
'loop' enters the recursion you can pass a different value, such as
counter + 1.

> replaceBasedIdx :: String -> [String] -> String -> String
> replaceBasedIdx findStr replaceStrList myText = replaceBasedIdxSub findStr replaceStrList myText

> replaceBasedIdxSub :: String -> [String] -> String -> String
> replaceBasedIdxSub findStr replaceStrList myText = loop 0 myText
>   where
>     loop :: Int -> String -> String
>     loop counter [] = []
>     loop counter myText =
>       let (prefix, rest) = splitAt n myText
>       in if findStr == prefix
>          then (replaceStrList !! counter) ++ loop (counter + 1) rest
>          else head myText : loop counter (tail myText)
>
>     n :: Int
>     n = length findStr

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Roel van Dijk | 8 May 10:03 2013
Picon

Re: Incrementation fails

> problem = replaceBasedIdx "X" ["b","d","f"] "aXcXeXgX"
> -- "abcdefg*** Exception: Prelude.(!!): index too large

This problem occurs because you never check if 'counter' is a valid
index in the 'replaceStrList'. You can solve it by not using the !!
operator at all. The solution is to also pass 'replaceStrList' in the
recursion. That way you can check whether you have exhausted all
strings in that list and as a bonus you do not need your counter
anymore:

> replaceBasedIdx :: String -> [String] -> String -> String
> replaceBasedIdx findStr replaceStrList myText = loop replaceStrList myText
>   where
>     loop :: [String] -> String -> String
>     loop rs [] = []
>     -- Check for empty list of replacements
>     loop [] text = text
>     -- Pattern match on the list of replacements to get both the
>     -- entire list rs, the first element r and the tail rs'.
>     loop rs <at> (r:rs') text =
>       let (prefix, rest) = splitAt n text
>       in if findStr == prefix
>          then r ++ loop rs' rest
>          else head text : loop rs (tail text)
>
>     n :: Int
>     n = length findStr



2013/5/8 Roel van Dijk <vandijk.roel <at> gmail.com>
I stared at the code some more and deduced what I think is the
intented meaning. Occurences of 'findStr' in 'myText' are replaced
with the strings in 'replaceStrList'.

So replaceBasedIdx "X" ["b","d","f"] "aXcXeXg" = "abcdefg"

The reason your counter didn't increment is because it was defined as
an argument to 'replaceBasedIdxSub'. That means its value is fixed
once you evaluate that function. Its value will not change no matter
how many times the inner 'loop' function is evaluated. The solution is
to pass the counter as an argument to said 'loop' function. Now when
'loop' enters the recursion you can pass a different value, such as
counter + 1.

> replaceBasedIdx :: String -> [String] -> String -> String
> replaceBasedIdx findStr replaceStrList myText = replaceBasedIdxSub findStr replaceStrList myText

> replaceBasedIdxSub :: String -> [String] -> String -> String
> replaceBasedIdxSub findStr replaceStrList myText = loop 0 myText
>   where
>     loop :: Int -> String -> String
>     loop counter [] = []
>     loop counter myText =
>       let (prefix, rest) = splitAt n myText
>       in if findStr == prefix
>          then (replaceStrList !! counter) ++ loop (counter + 1) rest
>          else head myText : loop counter (tail myText)
>
>     n :: Int
>     n = length findStr


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Gmane