查找和替换文本文件输出中的单词

时间:2011-03-20 21:34:07

标签: haskell

我对haskell失败了,我在尝试使这个脚本工作时遇到了相当大的麻烦。目的是让它从命令行读取参数并在单独的文本文件中找到它们。然后将这些单词替换为与单词长度相同数量的星号。我设法让它找到替换字,但从那以后就撞墙了。我尝试了各种各样的,并希望有人能够为我澄清它。

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 | lowercase(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

这个想法是调用convertWord部分并创建星号字符串以反馈到要在输出中显示的redact。但是,当我尝试编译它时,GHC返回错误“redact.hs:28:13:解析错误(可能是错误的缩进)”

提前感谢您提供的任何帮助

汤姆

2 个答案:

答案 0 :(得分:6)

你想要一个带字符串的函数"hello",并将其转换为"*****"(两者的长度均为5),这是正确的吗?

只需使用map (const '*')(这是一个函数:))。示例:map (const '*') "hello"产生"*****"

还有另一种变体,输入参数必须是[Char],而不是[a]。为此使用map (asTypeOf '*')。但是你可能不需要这个。

我真的不确定你想要什么。也许您可以澄清一下您的示例给出您希望函数执行的示例运行。

哦,您的编译错误是由于您以奇怪的方式使用where语法。 :)

希望这有帮助!

答案 1 :(得分:1)

我试着给你一些关于代码的更多灵感:

我看到的第一件事是你解构参数列表并将其提供给redact。这不是很好,因为你不能提供超过5个单词。如何将列表作为参数并使用lowercase w \ elem` map小写wList`来检查条件?

另一件事是列表理解。如果您不想利用它的特殊功能,那么使用map通常很简单。还将Tarrasch的提示应用于您的代码,它可能如下所示:

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 '*')

在Haskell中,您将很快学会如何根据地图和折叠进行思考。一旦习惯了它们,你几乎只会使用库函数;很少需要显式递归。