I came up with this function rangedReplace as an exercice to use recursion and try different ways to make it work (I made at least 3 completely different versions). I think this version is the best but I have a feeling I can improve the way the functions/arguments are handled especially in the censor and in the main functions. How can I get these functions to be more idiomatic Haskell-way of doing, ?-- Replace the letters in the range [from:to[ (to not included) with chrrangedReplace :: Int -> Int -> Char -> String -> StringrangedReplace from to chr str     | from == to = str    | otherwise  = (take from' str) ++ rangedReplace' chr n (drop from' str)    where from' = min from to          to'   = max from to          n     = to' - from'-- Helper functionrangedReplace' :: Char -> Int -> String -> StringrangedReplace' chr n str    | n == 0    = str    | str ==  =     | otherwise = chr : (rangedReplace' chr (n-1) (tail str))Usage example:censor (from,to) = rangedReplace from to '*'main = do    putStrLn $ foldr id Fork bombs (map censor [(1,3),(6,8)]) 
Replacing part of a string with filler characters
strings;haskell
Parameter designTo facilitate currying, you should arrange a function's parameters starting with the one that is the least likely to vary.  In this case, I would consider the fill character the parameter that is most likely to be fixed.The next parameter, I think, should be the range, and it should be specified as a pair rather than as two separate parameters.  That would make rangedReplace fill (from, to) a filter that takes a string and produces a string.Using inclusive bounds for from and exclusive bounds for to is the right way to go.I don't think it's beneficial to automatically swap from and to.  That just encourages your caller to be sloppy.  Rather, I would expect a rangedReplace from 3 to 1 to act as a no-op.With rangedReplace fill (from, to) string, your main function no longer needs id, map, and the censor helper function.main = do  putStrLn $ foldr (rangedReplace '*') Fork bombs [(1, 3), (6, 8)]ImplementationThe use of ++ should be considered a yellow flag, as it indicates a full list traversal.  You'll be doing three O(from') operations: take, drop, and ++.I'd rather go with a recursive solution that does everything in one pass, and is fully lazy.  The implementation is shorter, too.rangedReplace :: Char -> (Int, Int) -> String -> StringrangedReplace _ _ [] = []rangedReplace fill (from, to) s@(c:cs)  | to <= 0   = s  | from <= 0 = fill:cs'  | otherwise = c:cs'  where cs' = rangedReplace fill ((from - 1), (to - 1)) cs