나는 당신이 당신의 문제를 해결하는 데 도움이되는 몇 가지 힌트를 줄 것이다.
첫째, 정의한 모든 기능에 유형을 제공하는 것은 큰 도움이됩니다. 이렇게하면 컴파일러가 함수가 자신이 생각하는대로 수행하지 않는 경우 즉시 알려줍니다. 또한 프로그램의 다른 부분을 함께 참여시켜야 할 때 도움이됩니다.
둘째, 함수 당 하나의 문제 만 해결하는 것이 좋습니다. 귀하의 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)
당신이 지금 붙어있는 경우 당신은 설명하지 않았습니다. 당신의 생각의 기차는 무엇입니까, 무엇이 실업 결과를 얻기 위해 누락 되었습니까? – evnu
else 분기의 return 문. 나는 필요한 결과를 얻기 위해 어떻게 부를 필요가 있는가를 의미한다. –
"반환 된"표현식 (return은 C의 반환과 동일하지 않음)은 함수의 서명에 예상되는 유형과 일치해야합니다. 따라서,'return'은 IO 모나드에 무언가를 들어 올려야합니다. 즉, 문자열의 튜플을 반환해야합니다. – evnu