How can I remove a certain character from a string in Haskell? - haskell

I want to make a function that removes a given character from a string.
The prototype is: removeChar :: Char -> String -> String
I tried to do something like this:
removeChar a x = foldr (++) [] (map (\x -> filter f x) x)
where
f x = elem a x

this should be enough, String is nothing but a [Char] so just filter it for that char
removeChar::Char->String->String
removeChar a = filter (/=a)

Related

how to find a certain char in string and replacing it with the spaces, left in that string with anonymous function in haskell

I need to write a function ,with the use of foldl, which recieves a string "str"
and returns an anonymous function. The anonymous functions receives a char 'c' and exchanges every instance of 'c' in "str" with the remaining number of chars in the string "str"
speak :: String -> (Char -> String)
example:
"Hello" 'e' -> "H3llo"
"gate" 't' -> "ga1e"
I've tried this code, but cant get it to work properly:
speak :: String -> (Char ->String)
speak str = foldl (\x -> if x == str then x = show(length str) else str) str
You can not assign a value to x What you need to do is either return show (length xs) ++ xs in case the character x is the same as the one you are looking for, or x:xs (so a normal prepend of x to xs) in case it does not match. Your speak also has a Char as first parameter, and then converts a String to a String, so:
speak :: Char -> String -> String
speak c = foldr (\x xs -> if c == x then show (length xs) ++ xs else (x:xs))
or with swapped parameters:
speak :: String -> Char -> String
speak str c = foldr (\x xs -> if c == x then show (length xs) ++ xs else (x:xs)) str

Is there an easier way to write this function and only using prelude from Haskell?

So I'm pretty new to Haskell, and are trying to solve an assignment, I've solved it, but I'm wondering if there is an easier or prettier way to make a function do the same as my wordChange. I'm trying to only use what is already in prelude.
dictionaryChecker _ [] = False
dictionaryChecker word (x:xs) = if elem word (snd x) then True else dictionaryChecker word xs
wordChange :: String -> String
wordChange str = unwords (map (\s -> if length (translate s) > 0 then (translate s)
else if (dictionaryChecker s dictionary) then concat (replicate (length s) "*")
else s) (words str))
translate :: String -> String
translate str = contains str dictionary
contains _ [] = ""
contains str (x:xs) = if elem str (snd x) then fst x else contains str xs
I'd suggest to use the lookup function from Prelude, which takes a key and a list of tuples (a.k.a a dictionary) and returns Maybe value. This simplfies your function a lot. Also, if changeWord uses a dictionary, it should be explicit instead of using a global variable. Below, a partial solution: since it is an assignment I think you should try to complete it ;)
changeWord :: [(String, String)] -> String -> String
changeWord dic s = unwords $ substitute ws
where -- ws is just the list of words s has
ws = words s
-- the function substitute does the word changing recursively. Try to complete it
substitute [] = []
substitute (x:xs) =
case lookup x dic of -- look for x in the dictionary and returns the value if found
Nothing -> undefined --complete
Just y -> undefined --complete
An obfuscated answer: earn a gold star from your professor if you can explain how it works, and be accused of copying from the internet if you can't:
wordChange :: [(String, String)] -> String -> String
wordChange dict = unwords . map (foldr const <*> (`lookup` dict)) . words
Your dictionaryChecker is in essence an any :: Foldable f => (a -> Bool) -> f a -> Bool with elem word . snd as condition:
dictionaryChecker :: (Foldable f, Foldable g, Eq a) => a -> f (b, g a) -> Bool
dictionaryChecker word = any (elem word . snd)
as for a translate, we can work with a section of an infix operator [Haskell-wiki] to make a point-free function:
translate :: String -> String
translate = (`contains` dictionary)
and for contains we can work with a foldr :: Foldable f => (a -> b -> b) -> b -> f a -> b
contains :: (Foldable f, Foldable g, Eq a) => a -> f (String, g a) -> String
contains str = foldr (\x y -> if … then … else …) ""
I leave implementing the … parts as an exercise.

Haskell transpose chars in String

I'm trying to write a function of the form:
f :: String -> [String]
f st = ...
It should display all possible transposions of chars in the String.
For example:
ghci> f "string"
["tsring","srting","stirng","strnig","strign"]
As you can see it should only transpose the next char with the current one.
I currently have:
f :: String -> [String]
f [] = []
f (x:xs) = ...
but i dont know how to actually transpose the chars.
f :: String -> [String]
f (x:y:xs) = (y:x:xs) : map (x:) (f (y:xs))
f xs = []
Note, that f [x] returns [], but it's easy to fix, if this is desired.

Substitue String in Haskell

Evening,
This is my attempt at an equivalent of "str_replace" in Haskell
strReplace :: (Char, Char) -> String -> String -> String {- Original (y) Parsed (z) -}
strReplace _ "" y = y
strReplace x y z = if (y !! 0) == fst x then strReplace x (drop 1 y) (z:([snd x])) else strReplace x (drop 1 y) (z:(y!!0))
Essentially, the first Tuple is the char to be substitued (Ie ('A', 'B') replaces all As to Bs, the second parameter is the String to be parsed and the third parameter should always be left an empty string. Compiler returns
*** Expression : z : [snd x]
*** Term : z
*** Type : [Char]
*** Does not match : Char
Ideas? :)
The problem with your code is that z : [snd x] is incorrect, z is a list but : wants it to be an element. This can be fixed by using z ++ [snd x].
If seeing the type signatures helps
(:) :: a -> [a] -> [a]
(++) :: [a] -> [a] -> [a]
Or in your specific case
(:) :: Char -> String -> String
(++) :: String -> String -> String
If I may suggest a few improvements to your code however, first strReplace shouldn't force you to pass an empty string
strReplace :: (Char, Char) -> String -> String
Next, we can do this two ways, using higher order functions or explicit recursion.
-- recursion
strReplace _ "" = "" -- Base case
strReplace (a, b) (c:cs) | a == c = b : strReplace (a,b) cs
| otherwise = c : strReplace (a, b) cs
So here if the string is empty we're done, otherwise we pattern match, if the first character is the one to be replaced, we replace it and recurse, otherwise we don't replace it and recurse.
This can actually be done much more cleanly with map though
strReplace (a, b) s = map (\c -> if c == a then b else c) s
This works identically to our previous version, but map abstracts out the looping logic.
z is of type [Char]. You can't use : to cons a [Char] into a [Char] - look at the type signature for :. You would have to use ++ to append one [Char] to another.
Additional points:
It would be better style for strReplace to have a signature :: Char -> Char -> String -> String -> String.
It would be even better style for the signature to be :: a -> a -> [a] -> [a] -> [a]
You shouldn't require the calling code to pass in an empty string. What if they don't - how will they know they made an error? If your recursive call requires it, use an inner function (using let or where).
Where you see a function that looks like foo x y = if (y == ... ) ... else ... it can almost always be improved by either pattern matching or guards.
To expand on point 4, you could rewrite that third line as
strReplace x y z | y !! 0 == fst x = ...
| otherwise = ...
Even better, if you took my advice in point 1 and split the tuple into two simple Char parameters, you could do this:
strReplace x1 x2 y#(y1:ys) z | x1 == y = ...
| otherwise = ...

Identifying repeating consecutive digits on the end of a String in haskell

So I write a function with the definition
getLastDigits :: String -> String
which finds repeating digits on the end of a String
So, for example.
getLastDigits "1000" should give "000"
getLastDigits "19990299" should give "99"
Coming from a java background I'm not quite sure how to structure this program. I'm thinking of using foldr but I'm fairly sure I can't stop the fold half way when the repeating digits end.
-edit solved. Use the group function.
Okay then, if it is not homework:
lastDigits :: String -> String
lastDigits s = firstDigits . reverse $ s
where firstDigits :: String -> String
firstDigits (x:xs) = x : takeWhile (== x) xs
firstDigits [] = []
import Data.Char (isDigit)
getLastTheSame :: Eq a => (a -> Bool) -> [a] -> [a]
getLastTheSame pred xs = f (reverse xs)
where f (y : ys) | pred y = y : takeWhile (== y) ys
f _ = []
lastDigits :: String -> String
lastDigits = getLastTheSame isDigit
You say you want repeating digits from the end of the string. I presume that if the last character is not a digit then you want the empty string returned.
Recall that type String = [Char].

Resources