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代码进行错误处理?
一种选择是使用(.&&.)和(.||.)来自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模块.