packages feed

zio-0.1.0.0: README.md

# haskell-zio

A [small](src/ZIO/Trans.hs) monad-transformer analogue to the
Scala [ZIO](https://github.com/zio/zio)
library (basically, [UIO](http://hackage.haskell.org/package/unexceptionalio) +
[Reader](hackage.haskell.org/package/transformers/docs/Control-Monad-Trans-Reader.html) +
[Either/ExceptT](hackage.haskell.org/package/mtl/docs/Control-Monad-Except.html)).

I like to call `ZIO` a *best-practices monad for applications*. It
wraps in a `Reader` monad for carrying around configuration and
environment data, and slightly more controversially, makes
error-handling more explicit by making all recoverable\
[exceptions and errors](https://wiki.haskell.org/Error_vs._Exception)
part of the return-type of functions.

Note that this is meant to provide the same basic functionality of the `ZIO` monad.
While I'm not immediately looking into other features of ZIO-the-library, such as
concurrency, I welcome suggestions via issues or pull requests.

## Comparison to other Haskell libraries

- [UIO](http://hackage.haskell.org/package/unexceptionalio) This ZIO library
builds upon UIO (Unexceptional-IO) as a dependency, and it is the
inner-most monad in the transformer stack. We use UIO, in conjunction
with `ExceptT`, to model possible error states (or the lack thereof)
more explicitly. In other words, we are trying to make all errors or
exceptions.
[checked exceptions](https://en.wikibooks.org/wiki/Java_Programming/Checked_Exceptions), where possible. See the [blog post](https://singpolyma.net/2018/05/error-handling-in-haskell/) (or [backup](docs/UIO.md)) for more details.
- [RIO](https://hackage.haskell.org/package/rio)
[integrates](hackage.haskell.org/package/rio/docs/src/RIO.Prelude.RIO.html#RIO) `ReaderT` with `IO`, but somewhat like Scala ZIO, provides
much additional functionality, and providing much of that functionality\
will be a goal of haskell-zio as well.
- [Trio](https://github.com/snoyberg/trio) has essentially the same goals
as ZIO (and I believe it is isomorphic to ZIO), but is a self-described
experiment at the moment. The major experimental aspect I'm aware of is
that it is avoiding usage of `ExceptT` to improve performance, which
I have not investigated. We are currently aiming for stability here,
but ideally any code written for haskell-ZIO could easily be transferred
to using `Trio`, or vice versa. If you see a difference, **please raise an
issue** so we can document it or fix it.

## The Scala-Haskell ZIO dictionary

### Type Aliases
The Scala ZIO type parameters and
[aliases](https://zio.dev/docs/overview/overview_index#type-aliases) are
largely reproduced in Haskell, though in some cases we can't exactly
reproduce them. For instance, `IO` is already taken in Haskell at
a very fundamental level. As well, `UIO` has the same meaning as in
the Scala implementation, but it isn't an alias, since it is an inner
monad of the `ZIO` type.

An apparent downsize of having `UIO`, `EIO`, and `ZIO` as distinct
(non-aliased) types is that one might feel inclined to provide APIs
for one or more of these when warranted. For this reason `UEIO e`,
`UZIO a`, and other aliases along with associated lift and unlift
functions are provided. These aliases have `Void` in the expanded type,
and in some cases, it is more appropriate to use a universal quantifier,
e.g., when lifting into a type, we usually have some Error type in mind
other than `Void` (that's one big reason why we're using this library!),
so we'd prefer to have e.g. `uelift :: ∀ e a. UIO a -> EIO e a`,
not `uelift :: UIO a -> UEIO a`.

[//]: # (Table generated from docs/type_aliases.csv using https://www.tablesgenerator.com/markdown_tables)

| Haskell Type 	| Alias for                           	| Scala Type   	| Notes                                                                                                 	|
|--------------	|-------------------------------------	|--------------	|-------------------------------------------------------------------------------------------------------	|
| `ZIO r e a`  	|                                     	| `ZIO[R,E,A]` 	|                                                                                                       	|
| `UIO a`      	|                                     	| `UIO[A]`     	| This is a type alias in Scala but a concrete type in Haskell due to UIO being an inner monadic type.  	|
| `EIO e a`    	|                                     	| `IO[E, A]`   	| This is a type alias in Scala but a concrete type in Haskell due to EIO being an inner monadic type.  	|
| `RIO r a`    	| `ZIO r SomeNonPseudoException a`    	| `RIO[R, A]`  	| Same idea as in Scala. Not to be confused with the RIO library's `RIO` monad, but they are isomorphic. 	|
| `Task a`     	| `ZIO Void SomeNonPseudoException a` 	| `Task[A]`    	|                                                                                                       	|
| `UEIO a`     	| `EIO Void a`                        	| `UIO[A]`     	|                                                                                                       	|
| `URIO r a`   	| `ZIO r Void a`                      	| `URIO[R, A]` 	| Same idea as in Scala; a ZIO value isomorphic to a RIO value (can be projected to the RIO value).     	|
| `UZIO a`     	| `ZIO Void Void a`                   	| `UIO[A]`     	|                                                                                                       	|