1

我有以下代码:

foldM (\exitCode args -> pure exitCode .&&. someCmdWith args) ExitSuccess argss

其中使用turtle' (.&&.)运算符。

有没有更好的抽象我可以用来应用于 apply to.&&.的结果?someCmdWithargss

4

2 回答 2

2

这行得通吗?

runCmds argss = foldr (.&&.) (pure ExitSuccess) (fmap someCmdWith argss)

如果您想写得更短,我相信这也可以:

runCmds = foldr (.&&.) (pure ExitSuccess) . fmap someCmdWith
于 2019-11-05T17:37:03.060 回答
2

(.&&.)看起来是关联的,似乎有一个中性元素 ( pure ExitSuccess) 所以让我们定义一个Monoid

newtype UntilFailure = UntilFailure { runUntilFailure :: IO ExitCode }

instance Monoid UntilFailure where
     mappend (UntilFailure a1) (UntilFailure a2) =  UntilfFailure (a1 .&&. a2)
     mempty = UntilFailure (pure ExitSuccess)

然后我们可以写如下内容:

runUntilFailure . foldMap UntilFailure $ someCmdWith <$> argss

定义 a 的好处Monoid是,每次折叠项目列表时,我们不必记住哪个是中性元素,因为它是“在类型中烘焙的”,可以这么说。

但是,我认为不能定义一个幺半群(.||.),因为中性元素必须以某种方式保留前一个命令的退出代码。不过,仍然可以定义 a Semigroup

于 2019-11-05T18:48:59.570 回答