2011-03-20 4 views
1

저는 haskell에 새로운 오류입니다.이 스크립트를 작동시키는 데 상당한 어려움을 겪고 있습니다. 의도는 명령 행에서 arguements를 읽고 별도의 텍스트 파일에서 찾아내는 것입니다. 이 단어들은 그 단어의 길이와 같은 양의 별표로 대체됩니다. 나는 그 단어를 대체하기 위해 그것을 얻을 수 있었지만 그 이후로 벽에 부딪쳤다. 나는 모든 것을 시도해 보았고 누군가가 나를 위해 그것을 명확히 할 수 있기를 희망했다.텍스트 파일에서 단어 찾기 및 바꾸기

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 부분이라는 것을 보여 주며, 출력에 표시하는 편집하다 다시 공급하는 별표 문자열을 생성한다. 내가이 컴파일 할 때 그러나, GHC 오류 "redact.hs을 : 28 : 13 : 오류 (아마도 잘못된 들여 쓰기) 구문 분석"반환하는 모든 도움에 미리

감사를 당신이

을 제공 할 수 있습니다
+3

한 가지 힌트는 코드에서 코드 중복을 피하려고합니다. 소문자 (w) == 소문자 (w1) = convertWord w 1 '을 모두 하나의 것으로 변환 할 수있는 방법에 대해 생각해보십시오. 절대 코드를 복사하지 않는 것이 좋습니다. :) – Tarrasch

+2

예를 들어, 다음과 같이 할 수 있습니다 :'소문자 w \'elem \'소문자 맵 [w1, w2, w3, w4, w5] – fuz

답변

6

문자열이 "hello"이라고하고, "*****" (둘 다 길이가 5 임)으로 변환하는 함수를 원한다면, 맞습니까?

간단히 map (const '*') (즉 기능 :)을 사용하십시오. 예 : map (const '*') "hello" 수율 "*****"

입력 인수가 [a]이 아닌 [Char]이어야하는 또 다른 변형이 있습니다. 그 때문에 map (asTypeOf '*')을 사용하십시오. 그러나 당신은 아마 이것을 필요로하지 않습니다.

나는 당신이 원하는 것이 확실하지 않습니다. 어쩌면 예제 을 사용하여 함수가 원하는 것을 실행할 수 있습니다.

아, 컴파일 오류는 이상한 방식으로 where 구문을 사용하기 때문에 발생합니다. :)

희망이 도움이됩니다.

내가 볼 첫 번째 것은, 당신이 인수 목록을 해체하고 redact으로 공급한다는 것입니다 :

+0

그게 정확히 제가 고맙다고 생각했던 것입니다! – espsquall

+1

@espsquall [많은 단어가 없습니다.] (http : //hyperboleandahalf.blogspot.com/2010/04/alot-is-better-than-everything.html) – ephemient

1

난 당신에게 코드에 대한 좀 더 많은 영감을 제공하려고합니다. 이것은 5 단어 이상을 제공 할 수 없으므로별로 좋지 않습니다. 어쨌든리스트를 인수로 취해서 lowercase w \ elem`map lowercase 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 '*') 

하스켈에서 신속지도와 주름의 관점에서 생각하는 방법을 배우게됩니다. 일단 익숙해지면 라이브러리 기능을 거의 독점적으로 사용할 수 있습니다. 명시 적 재귀는 거의 필요하지 않습니다.

+0

작은 말로 convertWord에'Eq a =>'가 필요 없다는 것입니다. – Tarrasch