Haskell IO monad并做表示法

Stu*_*ton 1 io monads haskell

以下Haskell snippit将无法编译,我无法弄清楚原因.

runCompiler :: TC -> IO ()
runCompiler tc = let cp' = cp in 
    do 
        cp'
        return ()
    where
    cp = compileProg tc
Run Code Online (Sandbox Code Playgroud)

我从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 () }
Run Code Online (Sandbox Code Playgroud)

任何想法如何使其编译.我不明白为什么它不接受()作为给出的最终值.

Lee*_*Lee 12

使用do符号排序时有两个语句:

do
    action1
    action2
Run Code Online (Sandbox Code Playgroud)

是相同的 action1 >> action2

既然>>Monad m => m a -> m b -> m b两种类型action1,action2应该是monadic值.

看来你的compileProg函数有类型TC -> String,而编译器期望它TC -> IO a适用于某些类型,a因为你在do表示法中使用它.

你可以使用 let

do 
    let _ = compileProg tc
    return ()
Run Code Online (Sandbox Code Playgroud)

让它编译.

如果要输出返回的字符串,可以使用putStrLnprint:

do
    putStrLn (compileProg tc)
    return ()
Run Code Online (Sandbox Code Playgroud)

既然putStrLn有类型String -> IO ()你可以删除return ():

do
    putStrLn (compileProg tc)
Run Code Online (Sandbox Code Playgroud)

实际上runCompiler可以简单地写成

runCompiler :: TC -> IO ()
runCompiler = putStrLn . compileProg
Run Code Online (Sandbox Code Playgroud)

  • @StuartPaton然后你想要`putStrLn(compileProc tc)` (2认同)