2013-04-05 61 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