在Turtle中编写ExitCodes.为什么没有Monad/Monad Transformer实例?

DJG*_*DJG 6 haskell haskell-turtle

我正在使用Haskell编写一个shell脚本,turtle并希望了解编写可能失败的命令的最佳实践.

现在我有一个案例表达式楼梯,如下所示:

runRemote :: MonadIO io => Text -> Text -> io ()
runRemote oldVersion' newVersion' = sh $ do
  mkdir "out"
  e1 <- shell ("command " <> oldVersion') empty
  case e1 of
    ExitFailure n -> cleanup 
    ExitSuccess -> do
      e2 <- shell ("command " <> newVersion') empty
      case e2 of
        ExitFailure n -> cleanup 
        ExitSuccess -> do
          curDir <- pwd
          cd (curDir <.> oldVersion')
          e3 <- shell ("command something else") empty
          case e3 of
           -- ...
           -- And so on...
Run Code Online (Sandbox Code Playgroud)

如果case表达式在Maybe类型上扩展,则解决方案是派生Monad实例.

有没有特殊原因库作者还没有派生Monad实例,ExitCode或者有更好的方法来对Haskell shell代码进行错误处理?

dup*_*ode 5

一种选择是使用(.&&.)(.||.)来自Turtle.Prelude.

(.&&.) :: Monad m => m ExitCode -> m ExitCode -> m ExitCode

类似于&&Bash

仅在第一个命令返回时运行第二个命令 ExitSuccess

(.||.) :: Monad m => m ExitCode -> m ExitCode -> m ExitCode

类似于||Bash

仅在第一个命令返回时运行第二个命令 ExitFailure

它们允许您像这样链接命令(请注意,所涉及的所有内容都必须返回ExitCode,包括清理):

(command1 .&&. command2) .||. cleanup
Run Code Online (Sandbox Code Playgroud)

或者,如果在每种情况下需要不同的清理操作:

(command1 .||. cleanup1) .&&. (command2 .||. cleanup2)
Run Code Online (Sandbox Code Playgroud)

顺便说一句,这是值得注意的是,ExitCode不被定义 而是由基地,中System.Exit模块.