Finding and replacing words in a text file output
I'm failry new to haskell and i'm having a fair amount of trouble trying to get this script to work. The intention is for it to read in arguements from a command line and find them in a seperate text file. These words are then replaced with asterisks of the same amount as the length of the word. I've managed to get it to find an replace the words but have hit a wall since. I've tried all sorts and was hoping someone may be able to clarify it for me.
module Main where
import System
import Data.Char
lowercase = map toLower
main = do (arg1:arg2:arg3:arg4:arg5:_) <- getArgs
txt <- getContents
putStr ( redact txt arg1 arg2 arg3 arg4 arg5 )
redact file w1 w2 w3 w4 w5 = unlines [ process line | line <- lines file ]
where process line = unwords [ f word | word <- words line ]
f w | l开发者_如何学Pythonowercase(w) == lowercase(w1) = convertWord w 1
| lowercase(w) == lowercase(w2) = convertWord w 1
| lowercase(w) == lowercase(w3) = convertWord w 1
| lowercase(w) == lowercase(w4) = convertWord w 1
| lowercase(w) == lowercase(w5) = convertWord w 1
| otherwise = w
convertWord :: Eq a => [a] -> [a] -> [a] -> [a]
convertWord [] _ = []
convertWord word count = temp
where if count == 1 then let temp = ""
if count <= length( word )
then temp = temp ++ "*"
convertWord word count+1
The idea is that the convertWord part is called and creates the string of asterisks to feed back to the redact to be displayed in the output. However, when i try to compile this, GHC returns the error "redact.hs:28:13: parse error (possibly incorrect indentation)"
Thanks in advance for any help you can offer
Tom
You want to have a function that takes a string say, "hello"
, and turns it into "*****"
(both have length 5), is that correct?
Simply use map (const '*')
(that is a function :)). Example: map (const '*') "hello"
yields "*****"
There is another variant where the input argument must be [Char]
, rather than [a]
. For that use map (asTypeOf '*')
. However you probably don't need this.
I'm really unsure what you want. Maybe you could clarify your example and give some example runs of what you want your functions to do.
Oh, your compilation error is due to you use the where
syntax in a weird fashion. :)
Hope this helps!
I try to give you some more inspiration about the code:
The first thing I see, is that you deconstruct the argument list and feed it into redact
. This is not very good, as you can't provide more than 5 words to it. How about taking a list as an argument and checking the condition using lowercase w \
elem` map lowercase wList`?
The other thing is the list comprehension. If you don't want to exploit it's special features, it's usually les verbose to use a map
. Also applied the tips of Tarrasch to your code, it may look like this:
module Main where
import System
import Data.Char
lowercase :: String -> String
lowercase = map toLower
main :: IO ()
main = do args <- getArgs
txt <- getContents
putStr ( redact txt args )
redact :: String -> [String] -> String
redact file wList = unlines . map process $ lines file
where process = unwords . map f . words
f w | lowercase w `elem` map lowercase wList = convertWord w
| otherwise = w
convertWord :: Eq a => [a] -> [a]
convertWord :: map (const '*')
In Haskell, you will quickly learn how to think in term of maps and folds. Once you get used to them, you will use library functions almost exclusively; explicit recursion is needed rarely.
精彩评论