1

I think my desire is quite forward.

So I have a string e.g. "abc1abc2abc3" I want to replace every number with the Char 'X' time the given Number. So "abc1abc2abc3" -> "abcXabcXXabcXXX"

I know i only get Integers <9 so I thought doing something like:

myFunction givenString = let
    replaceEveryNumber '1' = 'X'
    replaceEveryNumber '8' = "XXXXXXXX"
    replaceEveryNumber c = c
    in map replaceEveryNumber myFunction

And yeah this does not really work because of different types.

I could also apply a similiar function to a [String] for my desire. So I could change from the code above '1' = 'X' to "1" = "X" and so on, but the problem here is that if I have ["abc2abc", "8"] the result is ["abc2abc", "XXXXXXXX"] so it ignores the char in the String in !!0, which I guess makes sense but I still don't know how to do it correctly.

I hope someone can help me, thanks!

1 Answer 1

2

There are a few problems here. You are not mapping over givenString, but over myFunction. Since myFunction is a function, that will not work. We thus should replace the mapping expression with:

myFunction givenString = let … in map replaceEveryNumber givenString

Furthermore the replaceEveryNumber can only return values of one type, your function however returns a Char, and the other lines return a String. Since your function should be able to return a sequence of multiple Chars, we thus should return a string for every line. For c we will need to wrap it in a singleton list to convert the Char to a String with that character:

myFunction givenString = let
    replaceEveryNumber '1' = "X"
    replaceEveryNumber '2' = "XX"
    replaceEveryNumber '3' = "XXX"
    replaceEveryNumber '4' = "XXXX"
    replaceEveryNumber '5' = "XXXXX"
    replaceEveryNumber '6' = "XXXXXX"
    replaceEveryNumber '7' = "XXXXXXX"
    replaceEveryNumber '8' = "XXXXXXXX"
    replaceEveryNumber c = [c]
    in map replaceEveryNumber givenString

Now this will generate a list of Strings, for example:

Prelude> myFunction "abc1abc2abc3"
["a","b","c","X","a","b","c","XX","a","b","c","XXX"]

the only thing that we still need to do is concatenate these strings. We can make use of concat :: [[a]] -> [a], but we can also work with concatMap :: (a -> [b]) -> [a] -> [b]:

myFunction givenString = let
    replaceEveryNumber '1' = "X"
    replaceEveryNumber '2' = "XX"
    replaceEveryNumber '3' = "XXX"
    replaceEveryNumber '4' = "XXXX"
    replaceEveryNumber '5' = "XXXXX"
    replaceEveryNumber '6' = "XXXXXX"
    replaceEveryNumber '7' = "XXXXXXX"
    replaceEveryNumber '8' = "XXXXXXXX"
    replaceEveryNumber c = [c]
    in concatMap replaceEveryNumber givenString

Finally we do not need to write clauses for each digit. We can work with functions like replicate and digitToInt. I leave that as an exercise.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.