2013-04-05 81 views
1

下面的Haskell snippit不會編譯,我找不出原因。Haskell IO monad and do notation

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 2013-04-05 12:06:10

+1

爲什麼你將'compileProg tc'綁定到'cp''和'cp'?爲什麼你在同一個函數中同時使用'let'和'where'?這很混亂。 – 2013-04-05 12:22:03

+0

當我將它更改爲下面的答案時,它會編譯。現在我的問題是讓它輸出由compileProg返回的字符串。 – 2013-04-05 12:23:20

回答

12

當使用do符號測序兩個語句:

do 
    action1 
    action2 

相同action1 >> action2

>>已鍵入Monad m => m a -> m b -> m baction1action2應該是一元值。

看來你compileProg功能有類型TC -> String,而編譯器期望它是TC -> IO a一些a,因爲你是在do符號使用它。

您可以使用let

do 
    let _ = compileProg tc 
    return() 

得到它的編譯。

如果你想輸出返回的字符串,你可以使用putStrLnprint

do 
    putStrLn (compileProg tc) 
    return() 

因爲putStrLn的類型爲String -> IO()可以刪除return()

do 
    putStrLn (compileProg tc) 

事實上runCompiler可簡寫爲

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

我想要做的是在屏幕上顯示compileProg的輸出。 compileProg的類型簽名是TC - > String。 – 2013-04-05 12:19:26

+2

@StuartPaton然後你想'putStrLn(compileProc tc)' – drquicksilver 2013-04-05 12:24:00

+0

澄清@ lee的答案:'do'塊中的每個語句都有一個'IO a'類型(或者它可以是'let'綁定)。 'cp''有一個'String'類型,所以不會輸入check。 – 2013-04-05 12:25:20