[GHC] #14349: Semigroup/Monoid instances for System.Exit.ExitCode

GHC ghc-devs at haskell.org
Fri Oct 13 16:51:52 UTC 2017


#14349: Semigroup/Monoid instances for System.Exit.ExitCode
-------------------------------------+-------------------------------------
        Reporter:  neil.mayhew       |                Owner:  (none)
            Type:  feature request   |               Status:  upstream
        Priority:  low               |            Milestone:
       Component:  libraries/base    |              Version:  8.2.1
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by neil.mayhew):

 Maybe it would help to mention my use case, which is running a set of
 regression tests implemented as shell commands. (They pipe the output of
 an executable into a `diff` against the expected output. The exit status
 of the shell command is that of the `diff`.) The program that runs the
 regression tests is then used as a Cabal test suite (of type `exitcode-
 stdio`).

 (A simplified version of) the code looks like this:

 {{{#!hs
 {-# OPTIONS_GHC -fno-warn-orphans #-}

 import Data.Monoid (Monoid(..))
 import System.Process (system)
 import System.Exit (ExitCode(..), exitWith)

 instance Monoid ExitCode where
     mempty = ExitSuccess
     mappend ExitSuccess b = b
     mappend a           _ = a

 data MyTest = MyTest String

 tests :: [MyTest]
 tests = map MyTest
   [ "echo Test1"
   , "echo Test2"
   , "exit 3"
   , "echo Test4"
   , "exit 5"
   ]

 main :: IO ()
 main = mapM runTest tests >>= exitWith . mconcat

 runTest :: MyTest -> IO ExitCode
 runTest (MyTest cmd) = system cmd
 }}}

 To avoid the `Monoid` instance I could have the `runTest` function return
 a `Bool` instead, and use `and` to collect all the statuses:

 {{{#!hs
 main :: IO ()
 main = mapM runTest tests >>= bool exitFailure exitSuccess . and

 runTest :: MyTest -> IO Bool
 runTest (MyTest cmd) = (==ExitSuccess) <$> system cmd
 }}}

 However, the `Monoid` approach is more elegant because it avoids the
 repeated and redundant use of machinery from `System.Exit`.

 In both cases, the exit code of the test suite is `3`.

 It also happens that the `diff` output appears in the output of the test
 suite, and all the tests are run, rather than stopping at the first
 failure. So the output of the simplified test suite above is:

 {{{
 Test1
 Test2
 Test4
 }}}

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14349#comment:7>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list