# Feedback requested: Simple proposal to set program exit code by main's value

**URL:** <https://discourse.haskell.org/t/feedback-requested-simple-proposal-to-set-program-exit-code-by-mains-value/8687>\
**Category:** Uncategorized\
**Created:** [January 31, 2024, 1:40pm UTC](https://discourse.haskell.org/t/feedback-requested-simple-proposal-to-set-program-exit-code-by-mains-value/8687 "2024-01-31T13:40:09Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

**Author:** ![atravers](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@atravers](https://discourse.haskell.org/u/atravers)\
**Post date:** [January 31, 2024, 3:53pm UTC](https://discourse.haskell.org/t/feedback-requested-simple-proposal-to-set-program-exit-code-by-mains-value/8687/4 "2024-01-31T15:53:33Z")

</div>

For some time now I’ve been contemplating a generalisation of `main`:

```haskell
{-# LANGUAGE Haskell2010 #-}
import Foreign.Marshal -- see page 269 of 329 in the H. 2010 Report

class Mainly a where
    mainly :: a -> r

instance Mainly (IO a) where
    mainly act = unsafeLocalState (act >> exitSuccess)
                  -- or e.g. primMainlyIO :: IO a -> r 

```

With a suitable instance, any value can be _“returned”_ by `main :: Mainly a => a` e.g:

```haskell
instance Mainly ExitCode where
    mainly ecd = mainly (exitWith ecd)

instance Mainly Int where
    mainly n = mainly (ExitFailure n) -- ...but also see page 299 of the Report

instance Mainly Bool where
    mainly b = mainly (if b then 0 else 1)

instance Mainly () where
    mainly () = mainly (pure ())

              ⋮ 

```

From [Using unsafePerformIO safely?](http://discourse.haskell.org/t/using-unsafeperformio-safely/4146)

- 

> [@](#):
>
> [jaror:](http://discourse.haskell.org/t/using-unsafeperformio-safely/4146/9)
> 
> In the pure subset of Haskell throwing an exception is like entering an infinite loop. Exceptions thrown from within the unsafely performed IO are no different.

- 

> [@](#):
>
> [VictorCMiraldo:](http://discourse.haskell.org/t/using-unsafeperformio-safely/4146/14)
> 
> Memory can also run out making allocation in `bytestring` fail too…

- 

> [@](#):
>
> [VictorCMiraldo:](http://discourse.haskell.org/t/using-unsafeperformio-safely/4146/20)
> 
> […] if the code crashes, it would also have crashed had we placed `IO` everywhere anyway.

The presence of `Mainly.mainly` (or something like it) could help to bring more clarity to such matters. For example, if `throw` could be defined using `throwIO`:

```haskell
throw e = mainly (throwIO e)

```

then if `mainly m = ⊥` for all `m :: IO a` (as intended), `throw e` would also equal `⊥`, the result of an infinite regression or loop: `let y = y in y`. Similarly, if `m :: IO a` was going to end the program in some other way, then so would `mainly m :: r` .

---

_[View the full topic](https://discourse.haskell.org/t/feedback-requested-simple-proposal-to-set-program-exit-code-by-mains-value/8687)._
