2013-04-05 2 views
1

다음 하스켈 스니 피트는 컴파일되지 않으며 그 이유를 알 수 없습니다.하스켈 IO 모나드 및 노테이션

runCompiler :: TC -> IO() 
runCompiler tc = let cp' = cp in 
    do 
     cp' 
     return() 
    where 
    cp = compileProg tc 

나는 GHCi에서 다음과 같은 오류가 점점 오전 : 무엇을해야 하는지를

Couldn't match expected type `IO a0' with actual type `String' 
    In a stmt of a 'do' block: cp' 
    In the expression: 
     do { cp'; 
      return() } 
    In the expression: 
     let cp' = cp 
     in 
     do { cp'; 
      return() } 

어떤 아이디어가 컴파일 할 수 있습니다. 주어진 최종 값을 왜 받아 들일 수 없는지 나는 알 수 없다.

+3

compileProg의 유형 서명은 무엇입니까? – mhwombat

+1

왜'compileProg tc'를'cp '와'cp' 둘 다에 바인딩하고 있습니까? 왜 같은 기능에서'let'과'where'를 모두 사용하고 있습니까? 혼란 스럽네. –

+0

아래의 답변으로 변경하면 컴파일됩니다. 이제 내 문제는 그것을 출력 compileProg에 의해 반환 된 문자열을 만드는 것입니다. –

답변

12

do 표기 시퀀싱 두 문장 사용 :

do 
    action1 
    action2 

Monad m => m a -> m b -> m b 모두 action1action2 모나드 값이 입력되어야했다 >> 보낸 action1 >> action2

같은이다.

컴파일러는 당신이 do 표기법을 사용하고 있기 때문에 그것이 어떤 a에 대한 TC -> IO a있을 것으로 기대하면서 compileProg 기능, TC -> String을 입력가 나타납니다.

당신은이 let

do 
    let _ = compileProg tc 
    return() 

가 컴파일 얻을 수 있습니다.

는 사실
do 
    putStrLn (compileProg tc) 

runCompiler 수 있습니다 다음 return() 제거 할 수 putStrLn 이후

do 
    putStrLn (compileProg tc) 
    return() 

String -> IO()를 입력했다 : 당신이 출력에 반환 된 문자열을 원하는 경우에

, 당신은 putStrLn 또는 print 사용할 수 있습니다 간단히 표기 됨

runCompiler :: TC -> IO() 
runCompiler = putStrLn . compileProg 
+0

내가하고 싶은 일은 화면에 compileProg의 출력을 표시하는 것이다. compileProg의 형식 시그니처는 TC -> String입니다. –

+2

@StuartPaton 그런 다음에'putStrLn (compileProc tc)'를 입력하십시오. – drquicksilver

+0

@ lee의 대답을 명확히하기 위해서 : do 블록의 각 명령문은'IO a' 유형을가집니다 (또는'let' 바인딩이 될 수 있습니다). 'cp '는'String'의 타입을 가지므로 체크를하지 않습니다. –