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

GHC ghc-devs at haskell.org
Sat Nov 11 22:43:11 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):

 Since there's been no further discussion, I'll assume that's a no to my
 monoid proposal.

 However, I've been thinking about it some more, and I've come up with a
 solution that I think will be more acceptable (based on previous
 comments).

 Since `ExitCode` is structurally identical to `Maybe Int`, and since
 `Maybe` already has a lot of useful typeclass instances, I propose an
 isomorphism as follows:

 {{{#!hs
 -- | Case analysis for the 'ExitCode' type
 exitCode :: a -> (Int -> a) -> ExitCode -> a
 exitCode x _  ExitSuccess    = x
 exitCode _ f (ExitFailure i) = f i

 exitCodeToMaybe :: ExitCode -> Maybe Int
 exitCodeToMaybe = exitCode Nothing Just

 maybeToExitCode :: Maybe Int -> ExitCode
 maybeToExitCode = maybe ExitSuccess ExitFailure
 }}}

 Then it would be possible to use `Monoid` instances of newtype wrappers
 such as `First/Last` or use `Maybe`'s `MonadPlus` or `Alternative`
 instances. In particular, `msum`/`asum` has the behaviour I'm looking for:

 {{{#!hs
 >>> msum [Nothing, Just 1, Nothing, Just 3]
 Just 1
 }}}

 This would allow the following:

 {{{#!hs
 exitWith . maybeToExitCode . msum $ mapM (exitCodeToMaybe <$> system)
 commands
 }}}

 This could be further cleaned up:

 {{{#!hs
 exitWith' :: Maybe Int -> IO ()
 exitWith' = exitWith . maybeToExitCode

 system' :: String -> IO (Maybe Int)
 system' = exitCodeToMaybe <$> system

 main = exitWith' . msum . mapM system' $ commands
 }}}

 I would be in favour of providing `exitWith'` in `System.Exit` (eg as
 `exitWithMaybe`) but it's less easy to argue that `system'` should be
 provided (eg as `systemWithMaybe`) because there are several other
 functions in `System.Process` that return an `ExitCode` and it would be
 awkward to provide `Maybe` variants of all of them.

 So, is adding the isomorphism functions a possibility? What about
 `exitWithMaybe`?

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


More information about the ghc-tickets mailing list