문제

저는 현재 Haskell과 함께 프로젝트를 진행하고 있으며 문제를 발견했습니다. "dictionary.txt"파일의 각 줄을 목록에 읽고 삽입해야하지만 그렇게 할 수는 없습니다. 이 코드가 있습니다.

main = do
    let list = []
    loadNums "dictionary.txt" list

loadNums location list = do
    inh <- openFile location ReadMode
    mainloop inh list
    hClose inh

mainloop inh list = do 
    ineof <- hIsEOF inh
    if ineof
        then return ()
        else do 
            inpStr <- hGetLine inh
            inpStr:list
            mainloop inh list

"inpstr : list"를 "putstrln inpstr"으로 바꾸고 모든 줄을 표시하고 모든 줄을 표시하기 때문에 모든 줄을 얻는 것이 모든 줄을 가져와야하지만 목록에 삽입하지만 다음 오류가 발생합니다. :

Couldn't match expected type `IO' against inferred type `[]'

아마도 hgetline은 문자열이 아니라 IO 문자열이기 때문에 목록에 삽입 할 수있는 적절한 문자열을 얻기 위해 처리하는 방법을 모릅니다. 나는 이것이 어떻게 해결 될 수 있는지, 문제가 정확히 무엇인지 모르겠지만, 누군가가 파일의 모든 줄을 목록에 올바르게 가져 오는 방법에 대한 아이디어가 있다면 감사합니다.

미리 감사드립니다!

도움이 되었습니까?

해결책

오류가 발생하는 선에서 Haskell은 "io a"를 기대하고 있지만 []를 제공하고 있습니다. IO 모나드의 블록 블록에서 물건을 많이 단순화하면 모든 라인은 다음과 같습니다.

  • "io a"유형의 값을 반환하는 것; "A"유형의 값은 폐기됩니다 (따라서 "A"는 종종 "()")).
  • A <- 표현식은 같은 일을하지만 "A"값을 버리는 대신 <-의 왼쪽에 이름을 부여합니다.
  • a let, 값에 이름을 부여하는 것 이상

그 블록에서, "hgetline inh"는 "io 문자열"을 반환하고, 그 내 문자열이 추출되어 inpstrt라는 이름이 주어집니다. 다음 줄은 LET 또는 A <-도 아니기 때문에 "io a"유형이 있어야합니다. 당신이 대신 당신이 할 수있는 일, 당신은 이미 끈이 있기 때문에, 다음과 같습니다.

let list' = inpStr:list

이것은 문자열과 원래 목록으로 구성된 새 목록을 만들고 "목록"의 이름을 제공합니다.

"목록"대신 "목록" "을 사용하려면 다음 줄을 변경하십시오 (따라서 새 목록을 전달). 해당 라인은 (재귀 적으로) MainLoop을 호출합니다. MainLoop은 하나 더 읽고 자체적으로 전화를 걸고 있습니다. 전체 파일을 읽은 후 "io ()"유형으로 무언가를 반환합니다. 이 "io ()"는 LoadNums의 DO 블록으로 반환됩니다. 축하합니다. 방금 파일에서 읽은 줄을 리버스 순서로 (목록의 헤드에 추가했기 때문에) 목록을 만들었고 아무 것도하지 않았습니다.

무언가를하고 싶다면 "return ()"을 "리턴리스트"로 변경하십시오. 리턴은 "io [string]유형의 값을 생성하며, 목록은 그 안에 목록이 있습니다 (반환은 값을 캡슐화하는 것 이상).

나머지는 독자에게 운동으로 남겨 둡니다.

다른 팁

이것이 숙제 나 무언가를위한 것이 아니라면, 많은 노력을 기울일 이유가 없습니다. 재사용은 게으르다!

getLines = liftM lines . readFile

main = do
    list <- getLines "dictionary.txt"
    mapM_ putStrLn list

그러나 여전히 Haskell을 배우는 것처럼 보이면 Cesarb가 작성한 내용을 이해하는 것이 중요합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top