2012-06-10 4 views
0

숙제의 일부입니다. 입력에서 빈 줄까지 정보를 읽는 함수를 작성해야합니다. 이 함수는 첫 번째, 세 번째, 다섯 번째 ... 선 기호를 하나의 String으로, 두 번째, 네 번째 ...를 다른 String으로 둡니다. 서명 I String 다른 하나에 String 2,4,6- 기호를 인자로리스트를 취하고 1,3,5-두고 함수를 작성한 .. combine :: IO (String , String)haskell에서 입력 후 호출 함수

이다. 기능은 여기에 있습니다 :

intotwo (x : xs) 
    = let 
     (us , vs) 
     = intotwo xs 
    in 
    (x : vs , us) 
intotwo _ 
    = ([] , []) 

이 또한 내가 입력을 읽는 코드를 작성했습니다 : 그것은 여기에 있습니다 :

combine 
    = do 
     lines <- getLine 
     if null lines 
     then return ([], []) 
     else do 
      linesagain <- combine 
      return --what should I return? 

누군가가 내 숙제를 완료하는 데 도움이 수 (옵션 : 몇 가지 팁을 제공)?

+0

당신이 지금 붙어있는 경우 당신은 설명하지 않았습니다. 당신의 생각의 기차는 무엇입니까, 무엇이 실업 결과를 얻기 위해 누락 되었습니까? – evnu

+0

else 분기의 return 문. 나는 필요한 결과를 얻기 위해 어떻게 부를 필요가 있는가를 의미한다. –

+0

"반환 된"표현식 (return은 C의 반환과 동일하지 않음)은 함수의 서명에 예상되는 유형과 일치해야합니다. 따라서,'return'은 IO 모나드에 무언가를 들어 올려야합니다. 즉, 문자열의 튜플을 반환해야합니다. – evnu

답변

5

나는 당신이 당신의 문제를 해결하는 데 도움이되는 몇 가지 힌트를 줄 것이다.

첫째, 정의한 모든 기능에 유형을 제공하는 것은 큰 도움이됩니다. 이렇게하면 컴파일러가 함수가 자신이 생각하는대로 수행하지 않는 경우 즉시 알려줍니다. 또한 프로그램의 다른 부분을 함께 참여시켜야 할 때 도움이됩니다.

둘째, 함수 당 하나의 문제 만 해결하는 것이 좋습니다. 귀하의 intotwo 기능이 잘 다음과 같이, 그것은 아주 잘 목록을 분할의 직업 않습니다. 그러나 결합 기능은 너무 많이하려고하는 것처럼 보이므로 작성하기가 더 어려워집니다. 나는이 기능을 두 개의 작은 기능으로 분리 할 것이다.

마지막으로 undefined이라는 매우 유용한 특수 기능이 있습니다. 이는 모든 유형과 일치하며 함수를 작성하는 데 도움이됩니다. 트릭은 전체 함수가 정의되지 않은 상태 (그리고 컴파일 될 때 실행되지만 충돌 할 때)부터 시작하여 원하는 작업을 수행 할 때까지 점진적으로 함수를 개선하고 더 이상 정의되지 않은 함수가 없도록하는 것입니다.

그래서 먼저 intotwo 함수에 형식 시그니처를 추가합니다. 유형은 [a] -> ([a], [a])입니다.

다음은 빈 줄에 도달 할 때까지 입력에서 줄을 읽은 다음 읽은 줄의 목록을 반환하는 함수를 작성합니다.

readLinesUntilEmpty :: IO [String] 
readLinesUntilEmpty = undefined 

거의이 작업을 수행 구현이있다 :

readLinesUntilEmpty = do 
    nextLine <- getLine 
    rest <- readLinesUntilEmpty 
    return (nextLine : rest) 

그러나이 결코 읽는 없습니다 중지 (꽵이 비어있는 것을 확인하지 방법 주)이 기능은 유형이있다.

다음 함수

는이 작업을 수행 할 수있는 방법을 보여줍니다 (하지만 구현 밖으로의 일부를 떠날거야)

readLinesUntilEmpty = do 
    nextLine <- getLine 
    case nextLine of 
    "" -> do 
     undefined -- TODO fix me 
    _ -> do 
     undefined -- TODO fix me 

당신은 거기에서 나머지를 알아낼 수 있어야합니다.

다음으로 intotwo 함수는 두 개의 문자열 목록을 반환하지만 두 문자열을 다시 함께 결합해야합니다.예 : ["this", "that"]"this\nthat"이됩니다.

joinLines :: [String] -> String 
joinLines = undefined -- TODO 

이는 inttotwo의 FUNC보다 쓰기 쉬운 기능입니다, 그래서 당신은 괜찮을 것 : 이러한 기능의 유형은 [String] -> String입니다.

마지막으로, 당신은 당신의 결과를 얻기 위해 함께 그 세 가지 기능을 연결할 수 있습니다

combine :: IO (String, String) 
combine = do 
    lines <- readLinesUntilEmpty 
    let (oddLines, evenLines) = intotwo lines 
    return $ (joinLines oddLines, joinLines evenLines) 
0

여러 문자열 읽기가 필요하므로 재귀 입력이 필요합니다. 또는 getContents를 사용할 수도 있지만 대화 형 I/O에 적합한 지 여부는 확실하지 않습니다. 이 같은 뭔가 :

combine = getContents 
      >>= return . intotwo 
관련 문제