0

我尝试了什么:

main :: IO ()
main = do
  let eitherSuccessOrErrorLine = inshellWithErr "stack build" empty
  stackBuildOutput <- strict $ case eitherSuccessOrErrorLine of
    Shell (Left line)  -> line
    Shell (Right line) -> line
  putStr stackBuildOutput

错误信息:

src/Main.hs:34:12: error:
    • Couldn't match expected type ‘Turtle.Shell.FoldShell
                                      (Either Turtle.Line.Line Turtle.Line.Line) r0
                                    -> IO r0’
                  with actual type ‘Either (Shell Turtle.Line.Line) b0’
    • In the pattern: Left line
      In the pattern: Shell (Left line)
      In a case alternative: Shell (Left line) -> line
   |
34 |     Shell (Left line)  -> line
   |            ^^^^^^^^^

src/Main.hs:35:12: error:
    • Couldn't match expected type ‘Turtle.Shell.FoldShell
                                      (Either Turtle.Line.Line Turtle.Line.Line) r1
                                    -> IO r1’
                  with actual type ‘Either a0 (Shell Turtle.Line.Line)’
    • In the pattern: Right line
      In the pattern: Shell (Right line)
      In a case alternative: Shell (Right line) -> line
   |
35 |     Shell (Right line) -> line
   |            ^^^^^^^^^^
4

2 回答 2

1

解决方案是创建一个函数:

runStackBuild :: Shell ()
runStackBuild = do
  out <- inshellWithErr "stack build" empty
  liftIO $ putStrLn $ lineToText $ bifold out

并从以下位置调用它main :: IO ()

putStrLn "Starting `stack build`"
sh runStackBuild
putStrLn "Finished `stack build`"
于 2019-08-21T05:20:07.387 回答
1

问题是您试图对runShellWithErr. runShellWithErr确实返回 a Shell (Left Line) (Right Line),但Shell如此定义:

newtype Shell a = Shell { _foldShell:: forall r . FoldShell a r -> IO r }

这就是你的模式失败的原因。

与其尝试对 的结果进行模式匹配,不如从monadrunShellWithErr中提取行更简洁。像这样:EitherShell

main :: IO ()
main = do
    let successOrErrorLine = do
        buildOutput <- inshellWithErr "stack build" empty
        return $ case buildOutput of 
            Left line -> line
            Right line -> line
    result <- strict successOrErrorLine
    putStr $ show result

可以更简洁地完成

main :: IO ()
main = do
    let successOrErrorLine = (either id id) <$> (inshellWithErr "stack build" empty)
    result <- strict successOrErrorLine
    putStr $ show result

于 2019-08-21T08:56:09.533 回答