2012-01-25 2 views
3

"a 2"형식의 사용자 입력을 읽은 다음이를 튜플로 변환하고 튜플 목록에 추가하는 함수를 개발 중입니다. 이것은 사용자가 "done"을 입력 할 때까지 계속 발생합니다. 다음과 같이Haskell IO 함수 -> 유형 일치 오류

코드는이 파일을 실행하려고 할 때

getVectorData vector1 = do 
       putStrLn "Enter dimension and coefficient separated by a space: Enter \"Done\" to move on to next vector: " 
       appData <- getLine 

       if appData == "done" then 
        putStrLn "That's it" 
       else do 
        createVectorTuple (words appData) : vector1 
        getVectorData vector1 

createVectorTuple :: [String] -> (String, Float) 
createVectorTuple vectorData = ((head vectorData) , (read (last vectorData) :: Float)) 

어떻게 지금, 나는 오류 내가 잘못 뭐하는 거지

> ERROR file:.\MainApp.hs:13 - Type error in final generator 
*** Term   : getVectorData vector1 
*** Type   : IO() 
*** Does not match : [a] 

을 얻을 ...인가?

+0

참고로 createVectorTuple 함수는 잘 작동합니다. –

답변

4

IO을 순수한 비 IO 기능과 혼합합니다.

getVectorData vector1 = do 
    putStrLn "Enter dimension and coefficient separated by a space: Enter \"Done\" to move on to next vector: " 
    appData <- getLine 

    if appData == "done" then 
     putStrLn "That's it" 

위에 모든 IO

else do 
     createVectorTuple (words appData) : vector1 

createVectorTuple는 비 IO 함수이다. 이전 부분은 IO 덤프 블록이므로 해당 덤프 블록에 IO a 유형의 표현식 만 나타날 수 있습니다. 기능 응용 프로그램의 우선 순위가 가장 높은이기 때문에 위의 라인 타입 [(String, Float)]의 표현이다

(createVectorTuple (words appData)) : vector1 

을 구문 분석되도록 (vector1은 해당 유형이있는 경우) 그러나, 다소 이상한 오류 메시지가 표시됩니다. 이제 []도 모나드이므로 do 블록에 [a]의 표현식이 나타날 수 있지만 그 블록의 모든 표현식에는 목록 유형이 있어야합니다. 그러나

 getVectorData vector1 

위 부분에서 결정된 바와 같이 형태 IO()의 표현이다. 따라서 유형이 일치하지 않습니다. 틀림없이,보고 된 유형 오류는 그 상황에서 가능한 가장 명확하지 않습니다.

당신은 아마

let vector2 = createVectorTuple (words appData) : vector1 
getVectorData vector2 

또는 뭔가 완전히 다른의 라인을 따라 뭔가를 원한다, 나는 짧은 조각에서 말할 수 없다.

2

그게 좀 어렵지만 "createVectorTuple은"IO() "유형이 아니므로 실제 문제 일 수 있습니다."do "절에는 여러 가지 유형이있을 수 있으므로 유형 유추가 잘못된 추측 "createVectorTuple"를 기반으로하고, 다음 줄은 생각과 일치하지 않기 때문에 다음 오류 메시지는 당신이 아마 말하고 싶은 것은

else 
    getVectorData $ createVectorTuple (words appData) : vector1 
0

당신이 원하는나요이다

:.

else do 
    let vector1 = createVectorTuple (words appData) 
    getVectorData vector1 
0

또한 putStrLn "That 's it"다음에 return을 입력해야합니다. 그래서 if의 두 가지 브랜치는 같은 타입을 가진다. 예 :

if appData == "done" then do 
     putStrLn "That's it" 
     return vector1 
    else getVectorData (createVectorTuple (words appData) : vector1)