one-0.0.1: src/Control/One.hs
{-# OPTIONS_GHC -Wall -Werror #-}
-- |
-- Type-class abstractions for data types with a singleton view, built on
-- [lens](https://hackage.haskell.org/package/lens).
--
-- == Overview
--
-- Many data types have a natural notion of containing \"exactly one\" element.
-- A 'Data.List.NonEmpty.NonEmpty' list always has a head. An 'Data.Functor.Identity.Identity' always wraps a single
-- value. A 'Data.Set.Set' might contain exactly one element. This library captures
-- these patterns with four type classes, arranged in two parallel hierarchies
-- corresponding to the lens and prism sides:
--
-- @
-- 'GetterOne' 'ReviewOne'
-- | |
-- 'HasOne' 'AsOne'
-- @
--
-- === Lens hierarchy (total access)
--
-- For types that /always/ contain exactly one element:
--
-- * 'GetterOne' — provides @'getOne' :: 'Control.Lens.Getter' x ('GetterOneItem' x)@ to
-- extract the element.
-- * 'HasOne' (superclass: 'GetterOne') — provides @'one' :: 'Control.Lens.Lens'' x ('OneItem' x)@
-- to both get and set the element. A default implementation is derived from
-- 'getOne' and 'setOne'.
--
-- === Prism hierarchy (partial access)
--
-- For types that /might/ contain exactly one element:
--
-- * 'ReviewOne' — provides @'reviewOne' :: 'Control.Lens.Review' x ('ReviewOneItem' x)@ to
-- construct a singleton value from an element.
-- * 'AsOne' (superclass: 'ReviewOne') — provides @'_One' :: 'Control.Lens.Prism'' x ('AsOneItem' x)@
-- to both construct and pattern-match singleton values. A default
-- implementation is derived from 'reviewOne' and 'matchOne'.
--
-- == Usage
--
-- === Constructing singleton values
--
-- >>> import Control.Lens (preview, review, set, view)
-- >>> import Data.Functor.Identity (Identity(..))
-- >>> import Data.List.NonEmpty (NonEmpty(..))
-- >>> import Data.Set (Set)
-- >>> review reviewOne 7 :: [Int]
-- [7]
--
-- >>> review reviewOne 7 :: Set Int
-- fromList [7]
--
-- >>> review _One 7 :: Maybe Int
-- Just 7
--
-- === Matching singleton values
--
-- >>> preview _One [7]
-- Just 7
--
-- >>> preview _One [1, 2]
-- Nothing
--
-- >>> preview _One (Nothing :: Maybe Int)
-- Nothing
--
-- === Getting and setting (total types)
--
-- >>> view one (1 :| [2, 3])
-- 1
--
-- >>> set one 9 (1 :| [2, 3])
-- 9 :| [2,3]
--
-- >>> view one (Identity 7)
-- 7
--
-- == Instances
--
-- Instances are provided for a wide range of standard types including:
--
-- * __Containers__: @[]@, 'Data.List.NonEmpty.NonEmpty', 'Data.Sequence.Seq',
-- 'Data.Set.Set', 'Data.Map.Map', 'Data.IntSet.IntSet', 'Data.IntMap.IntMap',
-- 'Data.HashSet.HashSet', 'Data.HashMap.Strict.HashMap'
-- * __Text and bytes__: 'Data.Text.Text', 'Data.ByteString.ByteString'
-- (strict, lazy, and short variants)
-- * __Maybe and Either__: 'Maybe', 'Either'
-- * __Newtypes__: 'Data.Functor.Identity.Identity', 'Data.Functor.Const.Const',
-- 'Data.Semigroup.First', 'Data.Semigroup.Last', 'Data.Semigroup.Min',
-- 'Data.Semigroup.Max', 'Data.Semigroup.Dual', 'Data.Semigroup.Sum',
-- 'Data.Semigroup.Product', 'Data.Semigroup.WrappedMonoid',
-- 'Data.Ord.Down', 'Control.Applicative.ZipList', 'GHC.Generics.Par1', 'Data.Tuple.Solo'
-- * __Tuples__: @(x, a)@
--
-- Types that always contain one element (e.g. 'Data.Functor.Identity.Identity',
-- 'Data.List.NonEmpty.NonEmpty', 'Data.Tuple.Solo') have instances for all four classes.
-- Types that might contain one element (e.g. @[]@, 'Maybe', 'Data.Set.Set')
-- have instances only for the prism side ('ReviewOne' and 'AsOne').
module Control.One (module O) where
import Control.One.AsOne as O
import Control.One.GetterOne as O
import Control.One.HasOne as O
import Control.One.ReviewOne as O