# 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