MIT licensed by Tweag
This version can be pinned in stack with:linear-base-0.3.0@sha256:6cdb3bd2c7fbdcd06f949e1b34cb3f8bb3b8290c21ff81a71938804ad874b284,6574

Module documentation for 0.3.0

Linear base

License MIT Build status Hackage Stackage

Linear base is a standard library for developing applications with linear types. It is named linear-base to be an analog to the original base package that ships with GHC.

The purpose of linear-base is to provide the minimal facilities you need to write practical Linear Haskell code, i.e., Haskell code that uses the -XLinearTypes language extension.

Motivation

Why do you need linear-base to write linear projects?

  1. Data types, functions and classes in base are not linear types aware. For instance, if n is a linearly-bound Int, the RHS of a definition cannot write n + 1 — this will not type check. We need linear variants of Num, Functors, Monads, ($), etc.

  2. This library exports new abstractions that leverage linear types for resource safety or performance. For example, there are new APIs for file and socket I/O as well as for safe in-place mutation of arrays.

Getting started

-XLinearTypes is released with GHC 9, and linear-base is released on Hackage and Stackage.

All source files with linear types need a language extension pragma at the top:

{-# LANGUAGE LinearTypes #-}

User Guide

If you already know what -XLinearTypes does and what the linear arrow a %1-> b means, then read the User Guide and explore the examples/ folder to know how to use linear-base.

You can also find a table comparing base and linear-base typeclasses here.

Learning about -XLinearTypes

If you’re a Haskeller who hasn’t written any Linear Haskell code, don’t fear! There are plenty of excellent resources and examples to help you.

Tutorials and examples

Reading material

Talks

Contributing

Linear base is maintained by Tweag.

To contribute please see the Design Document for instructions and advice on making pull requests.

Licence

See the Licence file.

Copyright © Tweag Holding and its affiliates.

Changes

Change Log

v0.3.0 (2022-10-26)

Full Changelog

Headline changes

  • Support GHC 9.4 in addition to GHC 9.2 and GHC 9.0 (GHC 9.0 is no longer tested though) #427 (matthew-healy)
  • Improvement of the resource-aware IO (RIO) monad’s interface
    • Add some Handle operations to RIO #425 (endgame)
    • The Handle type is now transparent, to make extensions of the API possible #428 (aspiwack)

Miscellaneous

Internal

v0.2.0 - 2022-03-25

Full Changelog

Breaking changes

  • Remove Prelude.Linear.asTypeOf #397 (tbagrel1)
  • Add (and use) linear generics for many classes #394 (treeowl)
    • Control.Functor.Linear.Functor, Data.Functor.Linear.{Functor,Applicative} can now be derived through Generically1
    • Data.Functor.Linear.Traversable cannot be derived directly, but one can get genericTraverse for a Generic1 type and then set traverse = genericTraverse
    • Data.Unrestricted.Linear.{Consumable,Dupable,Movable} can be derived through Generically
  • Rework Data.Monoid.Linear module (affects linear Semigroup and Monoid) #314 (sjoerdvisscher), #381 (tbagrel1)
    • Remove superclass constraint on Prelude.{Semigroup,Monoid} for Data.Monoid.Linear.{Semigroup,Monoid}. Data.Monoid.Linear.Monoid instances now have to define mempty
    • Add many missing instances of Data.Monoid.Linear.{Semigroup,Monoid}
    • Deprecate Data.Monoid.Linear.{Adding,Multiplying,getAdded,getMultiplied} in favor of Data.Semigroup.{Sum,Product} (reexported under Data.Monoid.Linear) which now have linear Semigroup and Monoid instance. Sum and Product inner values can be extracted linearly with pattern-matching
    • Data.Semigroup is no longer reexported as a whole under Data.Monoid.Linear. Instead, only newtypes with a linear Semigroup instance are reexported
  • Add missing fixity declarations for every operator of linear-base #386, (tbagrel1)
    • Unchanged (already present):infixr 0 $, infixl 1 &, infixr 2 ||, infixr 3 &&, infix 4 ==, /=, <=, <, >, >=, infixr 5 :>
    • Add: infixr 0 `lseq`, `seq`, $!
    • Add: infixl 1 <&>, >>=, >>, &
    • Add: infixr 3 ***
    • Add: infix 4 `compare`, `elem`
    • Add: infixl 4 <$>, <$, <*>, <*
    • Add: infixr 5 ++
    • Add: infixr 6 <>
    • Add: infixl 6 +, -
    • Add: infixl 7 *
    • Add: infixr 9 #., .>, .
    • Previously missing fixity declarations defaulted to infixl 9, so some code might subtly break when updating to v0.2.0
  • Improve consistency of module naming #383 (tbagrel1)
    • System.IO.Resource -> System.IO.Resource.Linear
  • Rework Data.V.Linear API #360 (tbagrel1)
    • Data.Functor.Linear.Applicative instance
    • empty :: forall a. V 0 a
    • consume :: V 0 a %1 -> ()
    • cons :: forall n a. a %1 -> V (n - 1) a %1 -> V n a
    • uncons# :: 1 <= n => V n a %1 -> (# a, V (n - 1) a #)
    • uncons :: 1 <= n => V n a %1 -> (a, V (n - 1) a)
    • elim :: forall (n :: Nat) a b f. IsFunN a b f => f %1 -> V n a %1 -> b
    • make :: forall (n :: Nat) a f. IsFunN a (V n a) f => f
    • fromReplicator :: forall n a. KnownNat n => Replicator a %1 -> V n a
    • theLength :: forall n. KnownNat n => Prelude.Int
    • dupV is now part of Data.V.Linear: dupV :: forall n a. (KnownNat n, Dupable a) => a %1 -> V n a
  • Replace dupV in the minimal definition of Data.Unrestricted.Linear.Dupable with dupR :: a %1 -> Replicator a #360 (tbagrel1) #365 (facundominguez)
    • Introduce a new data type Data.Replicator.Linear.Replicator, which represents an infinite linear stream producing values of type a, with a stream-like API and a Data.Functor.Linear.Applicative instance
    • Data.Unrestricted.Linear.Dupable no longer depends on Data.V.Linear
    • Add dup3, dup4, dup5, dup6, dup7
  • Polymorphise the type of some Prelude.Linear functions in levity and multiplicity #353 (treeowl)
    • ($) :: forall {rep} a (b :: TYPE rep) p q. (a %p-> b) %q-> a %p-> b
    • (&) :: forall {rep} a (b :: TYPE rep) p q. a %p-> (a %p-> b) %q-> b
    • ($!) :: forall {rep} a (b :: TYPE rep) p q. (a %p-> b) %q-> a %p-> b
    • (.) :: forall {rep} b (c :: TYPE rep) a q m n. (b %1-> c) %q-> (a %1-> b) %m-> a %n-> c
    • forget :: forall {rep} a (b :: TYPE rep). (a %1-> b) %1-> a -> b
  • Multiplicity-polymorphise the type of some Prelude.Linear functions #319 (aspiwack)
    • id :: a %q-> a
    • const :: a %q-> b -> a
    • asTypeOf :: a %q-> a -> a
    • seq :: a -> b %q-> b
    • curry :: ((a, b) %p-> c) %q-> a %p-> b %p-> c
    • uncurry :: (a %p-> b %p-> c) %q-> (a, b) %p-> c
    • runIdentity' :: Identity a %p-> a
  • Remove LinearArrow usage in Control.Optics.Linear and use FUN 'One instead #308 (sjoerdvisscher)
    • This change add a Data.Profunctor.Linear.Profunctor instance to FUN 'One
  • Add .Linear.Internal modules (and only export parts of them in publicly-exposed .Linear modules) #306 (ekmett)
    • Data.Array.Destination[.Internal]
    • Data.Array.Mutable.Linear[.Internal]
    • Data.HashMap.Mutable.Linear[.Internal]
    • Data.Set.Mutable.Linear[.Internal]
    • Data.Vector.Mutable.Linear[.Internal]
    • Foreign.Marshal.Pure[.Internal]
    • System.IO.Resource.Linear.[.Internal]
    • This principle has been applied for newly-created modules in the subsequent PRs

New additions

  • Add Data.Arity.Linear module containing type-level helpers to deal with n-ary linear functions and type-level structural integers #390 (aspiwack), #391 (tbagrel1)
  • Add void function to consume Control.Functor.Linear.Functor inner value #387 (tbagrel1)
  • Add inspection tests to check inlining of Data.Replicator.Linear.elim and Data.V.Linear.{make,elim} #367 (tbagrel1)
  • Add genericTraverse to Data.Functor.Linear for Generics.Linear.Generic1 types #366 (tbagrel1), #384 (aspiwack), #385 (treeowl)
  • Add Unsafe.toLinearN (and narrow the scope of some coercions in the module internals) #346 (treeowl)
  • Add newtype Data.Unrestricted.Linear.AsMovable to derive Consumable and Dupable from Movable #357 (tbagrel1)
  • Add Data.Unrestricted.Linear.{Consumable,Dupable,Moveable} instances for all Word and Int types #352 (googleson78)
  • Add benchmarks for Data.HashMap.Linear #338 (utdemir)
  • Add benchmarks for Data.Array.Mutable.Linear #331 (utdemir)
  • Add Data.Unrestricted.Linear.{Consumable,Dupable} instances to Data.V.Linear.V #324 (aspiwack)
  • Add Data.Unrestricted.Linear.UrT, the unrestricted monad transformer #304 (sjoerdvisscher)

Code improvements

  • Add robustness improvements to Data.Replicator.Linear.elim and Data.V.Linear.{make,elim} #364 (tbagrel1), #382 (tbagrel1), #390 (aspiwack), #391 (tbagrel1)
  • Add various optimisations for Data.HashMap.Linear #337 (utdemir)
  • Improve Data.Array.Mutable.Unlifted.Linear.map performance #334 (utdemir)
  • Remove one unsafeCoerce use from Unsafe.coerce #330 (utdemir)
  • Improve Prelude.Linear.seq performance #329 (utdemir)
  • Use safer Vector.fromArray in Data.Array.Mutable.Linear internals #327 (utdemir)
  • Remove some incomplete pattern matches in Data.List.Linear.{scanr,scanr1} #299 (utdemir)

CI/Tooling improvements

Documentation improvements

  • Change relative links for absolute ones in the README #401 (tbagrel1)
  • Add comparison table between Prelude and Prelude.Linear classes #368 (tbagrel1)
  • Add Hackage and Stackage badges #336 (utdemir)
  • Hide internal modules from haddock documentation #326 (utdemir), #363 (tbagrel1)
  • Add a note that GHC 9.2 fixes linear case in the user guide #320 (monoidal)
  • Replace #-> with %1 -> in the documentation #315 (sjoerdvisscher)
  • Fix rendering in Data.Unrestricted.Linear.Ur documentation #303 (sjoerdvisscher)
  • Fix a typo in Data.Array.Mutable.Linear.unsafeWrite documentation #301 (daig)
  • Add a list of introduction talks about linear types in the README #300 (aspiwack)
  • Improve developer documentation in Data.Array.Polarized.Push #294 (Divesh-Otwani)

v0.1.0 - 2021-02-09

  • Initial release