packages feed

linear-base-0.1.0: docs/DESIGN.md

# Design

## Overall architecture

Linear base is more than a copy of things from [`base`] with some function
arrows being replaced by linear arrows. Moreover, the goal is __not__ exact
compliance with `base`.

Linear base consists of the following:

* fundamental data structures, functions and classes that arise
  naturally from wanting to do any linear development (e.g.,
  `Ur` and `Consumable`),
* tools ported from [`base`] and from other critical haskell
  libraries, like `lens`,
* new APIs for using system resources, e.g., file I/O in
  [`System.IO.Resource`],
* new abstractions made possible by linear types, like monad-free
  mutable arrays in ([`Data.Array.Mutable.Linear`]).

There is a top-level `Prelude.Linear` that is meant to be imported _unqualified_.
It does not include functors, monads, applicatives and so on because there are
multiple sensible ways to give linear arrows to these things. See this [blog
post] for details. This prelude includes:

* linear variants of definitions in `Prelude`,
* a few pervasive utility definitions when programming with linear
  types.

## Module structure

* `Prelude.Linear` is public facing and meant for users of linear-base
  whereas `Prelude.Linear.Internal` is meant as an internal prelude for
  development in linear-base itself. It is down deep in the module
  hierarchy, used throughout linear-base while `Prelude.Linear` is at the top
  and no other modules import it.
* Modules that have `Internal` in the name are not meant to be
  public and have their functionality used and/or re-exported in
  public-facing modules.

## General implementation strategy

This is the strategy that we've followed so far for developing
`linear-base`:

1. If the definition is simple enough that there's only one sensible
   place to replace a function arrow by a linear arrow, do that.
   Example:

   ```haskell
   foldr :: (a #-> b #-> b) -> b #-> [a] #-> b
   foldr f z = \case
     [] -> z
     x:xs -> f x (foldr f z xs)
   ```

	Otherwise, implement each sensible variant of the definition in
    dedicated modules. For instance, this is the case with
    `Data.Functor`s and `Control.Functor`s (see this [blog post]).

2. The ideas behind new definitions that are just now possible with
   linear types vary and each have unique concepts that are not
   addressed by a general strategy. These should be documented below
   if one of the following is true:

   * there is an overarching concept that extends beyond a handful of
     modules. Or,
   * There is an explicit departure away from the direction of `base`.
     (E.g., we decide there should be different laws for some type
     class already in `base`.)

## Conventions

We have established the following conventions in this project:

* use full words for Qualified imports, not abbreviations. For
  instance, import `Data.Functor.Linear` as `Linear` and not as `F`
  for functor.
* All public modules have an export list.
* Pure functions which modify a container take the
container as the last parameter (similar to functions in `Data.Map`). Monadic functions on containers
take the containers as the first parameter
(similar to functions in `Control.Concurrent.MVar`). See [issue #147][issue-147] for some
more details.

[functors]: https://www.tweag.io/posts/2020-01-16-data-vs-control.html
[examples/Simple/FileIO.hs]: https://github.com/tweag/linear-base/tree/master/examples/Simple/FileIO.hs
[`Data.Unrestricted.Linear`]: https://github.com/tweag/linear-base/tree/master/src/Data/Unrestricted/Linear.hs
[`Num`]: https://github.com/tweag/linear-base/tree/master/src/Data/Num/Linear.hs
[`base`]: https://hackage.haskell.org/package/base
[`Data.Array.Mutable.Linear`]: https://github.com/tweag/linear-base/blob/master/src/Data/Array/Mutable/Linear.hs
[blog post]: https://www.tweag.io/posts/2020-01-16-data-vs-control.html
[contributor's guide]: ../CONTRIBUTING.md
[`System.IO.Resource`]: https://github.com/tweag/linear-base/blob/master/src/System/IO/Resource.hs
[issue-147]: https://github.com/tweag/linear-base/issues/147