(.&&.)
выглядит ассоциативно, и кажется, что есть нейтральный элемент (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
Хорошая вещь в определении Monoid
заключается в том, что нам не нужно запоминать, какой нейтральный элемент мы каждый раз сворачиваем в списке, так как он, так сказать, «запеченный в шрифте».
Я не думаю, что можно определить моноид из (.||.)
, поскольку нейтральный элемент должен каким-то образом сохранять код выхода предыдущей команды. Тем не менее, можно определить Semigroup
.