packages feed

one-0.0.2: src/Control/One/ReviewOneItem.hs

{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wall -Werror #-}

module Control.One.ReviewOneItem where

import Control.Applicative (Const, ZipList)
import Control.Lens (Review, unto, _Just, _Right, _Wrapped)
import qualified Data.ByteString as ByteString
import qualified Data.ByteString.Lazy as LazyByteString
import qualified Data.ByteString.Short as ShortByteString
import Data.Functor.Identity (Identity)
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HashMap
import Data.HashSet (HashSet)
import qualified Data.HashSet as HashSet
import Data.Hashable (Hashable)
import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap
import Data.IntSet (IntSet)
import qualified Data.IntSet as IntSet
import Data.List.NonEmpty (NonEmpty (..))
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Ord (Down)
import Data.Semigroup (Dual, First, Last, Max, Min, Product, Sum, WrappedMonoid)
import Data.Sequence (Seq)
import qualified Data.Sequence as Sequence
import Data.Set (Set)
import qualified Data.Set as Set
import qualified Data.Text as Text
import qualified Data.Text.Lazy as LazyText
import qualified Data.Text.Short as ShortText
import Data.Tuple (Solo (..))
import Data.Word (Word8)
import GHC.Generics (Par1)

-- $setup
-- >>> import Control.Lens (review)

class ReviewOneItem x where
  type ReviewOneItemElement x

  reviewOneItem :: Review x (ReviewOneItemElement x)

-- | >>> review reviewOneItem 7 :: [Int]
-- [7]
instance ReviewOneItem [a] where
  type ReviewOneItemElement [a] = a

  reviewOneItem = unto (: [])

-- | >>> review reviewOneItem 7 :: NonEmpty Int
-- 7 :| []
instance ReviewOneItem (NonEmpty a) where
  type ReviewOneItemElement (NonEmpty a) = a

  reviewOneItem =
    unto
      (:| [])

-- | >>> review reviewOneItem 7 :: Seq Int
-- fromList [7]
instance ReviewOneItem (Seq a) where
  type ReviewOneItemElement (Seq a) = a

  reviewOneItem =
    unto
      Sequence.singleton

-- | >>> review reviewOneItem 'a' :: Text.Text
-- "a"
instance ReviewOneItem Text.Text where
  type ReviewOneItemElement Text.Text = Char

  reviewOneItem =
    unto
      Text.singleton

-- | >>> review reviewOneItem 'a' :: LazyText.Text
-- "a"
instance ReviewOneItem LazyText.Text where
  type ReviewOneItemElement LazyText.Text = Char

  reviewOneItem =
    unto
      LazyText.singleton

-- | >>> review reviewOneItem 'a' :: ShortText.ShortText
-- "a"
instance ReviewOneItem ShortText.ShortText where
  type ReviewOneItemElement ShortText.ShortText = Char

  reviewOneItem =
    unto
      ShortText.singleton

-- | >>> review reviewOneItem 65 :: ByteString.ByteString
-- "A"
instance ReviewOneItem ByteString.ByteString where
  type ReviewOneItemElement ByteString.ByteString = Word8

  reviewOneItem =
    unto
      ByteString.singleton

-- | >>> review reviewOneItem 65 :: LazyByteString.ByteString
-- "A"
instance ReviewOneItem LazyByteString.ByteString where
  type ReviewOneItemElement LazyByteString.ByteString = Word8

  reviewOneItem =
    unto
      LazyByteString.singleton

-- | >>> review reviewOneItem 65 :: ShortByteString.ShortByteString
-- "A"
instance ReviewOneItem ShortByteString.ShortByteString where
  type ReviewOneItemElement ShortByteString.ShortByteString = Word8

  reviewOneItem =
    unto
      ShortByteString.singleton

-- | >>> review reviewOneItem ("key", 7 :: Int) :: Map String Int
-- fromList [("key",7)]
instance ReviewOneItem (Map k v) where
  type ReviewOneItemElement (Map k v) = (k, v)

  reviewOneItem =
    unto
      (uncurry Map.singleton)

-- | >>> review reviewOneItem ("key", 7 :: Int) :: HashMap String Int
-- fromList [("key",7)]
instance (Hashable k) => ReviewOneItem (HashMap k v) where
  type ReviewOneItemElement (HashMap k v) = (k, v)

  reviewOneItem =
    unto
      (uncurry HashMap.singleton)

-- | >>> review reviewOneItem (1, 7 :: Int) :: IntMap Int
-- fromList [(1,7)]
instance ReviewOneItem (IntMap v) where
  type ReviewOneItemElement (IntMap v) = (Int, v)

  reviewOneItem =
    unto
      (uncurry IntMap.singleton)

-- | >>> review reviewOneItem 7 :: Set Int
-- fromList [7]
instance ReviewOneItem (Set a) where
  type ReviewOneItemElement (Set a) = a

  reviewOneItem =
    unto
      Set.singleton

-- | >>> review reviewOneItem 7 :: HashSet Int
-- fromList [7]
instance (Hashable a) => ReviewOneItem (HashSet a) where
  type ReviewOneItemElement (HashSet a) = a

  reviewOneItem =
    unto
      HashSet.singleton

-- | >>> review reviewOneItem 7 :: IntSet
-- fromList [7]
instance ReviewOneItem IntSet where
  type ReviewOneItemElement IntSet = Int

  reviewOneItem =
    unto
      IntSet.singleton

-- | >>> review reviewOneItem 7 :: (String, Int)
-- ("",7)
instance (Monoid a) => ReviewOneItem (a, b) where
  type ReviewOneItemElement (a, b) = b

  reviewOneItem =
    unto
      (mempty,)

-- | >>> review reviewOneItem 7 :: Maybe Int
-- Just 7
instance ReviewOneItem (Maybe a) where
  type ReviewOneItemElement (Maybe a) = a

  reviewOneItem =
    _Just
  {-# INLINE reviewOneItem #-}

-- | >>> review reviewOneItem 7 :: Either String Int
-- Right 7
instance ReviewOneItem (Either a b) where
  type ReviewOneItemElement (Either a b) = b

  reviewOneItem =
    _Right
  {-# INLINE reviewOneItem #-}

-- | >>> review reviewOneItem 7 :: Identity Int
-- Identity 7
instance ReviewOneItem (Identity a) where
  type ReviewOneItemElement (Identity a) = a

  reviewOneItem =
    _Wrapped
  {-# INLINE reviewOneItem #-}

-- | >>> review reviewOneItem 7 :: Const Int String
-- Const 7
instance ReviewOneItem (Const a b) where
  type ReviewOneItemElement (Const a b) = a

  reviewOneItem =
    _Wrapped
  {-# INLINE reviewOneItem #-}

-- | >>> review reviewOneItem 7 :: First Int
-- First {getFirst = 7}
instance ReviewOneItem (First a) where
  type ReviewOneItemElement (First a) = a

  reviewOneItem =
    _Wrapped
  {-# INLINE reviewOneItem #-}

-- | >>> review reviewOneItem 7 :: Last Int
-- Last {getLast = 7}
instance ReviewOneItem (Last a) where
  type ReviewOneItemElement (Last a) = a

  reviewOneItem =
    _Wrapped
  {-# INLINE reviewOneItem #-}

-- | >>> review reviewOneItem 7 :: WrappedMonoid Int
-- WrapMonoid {unwrapMonoid = 7}
instance ReviewOneItem (WrappedMonoid a) where
  type ReviewOneItemElement (WrappedMonoid a) = a

  reviewOneItem =
    _Wrapped
  {-# INLINE reviewOneItem #-}

-- | >>> review reviewOneItem 7 :: Dual Int
-- Dual {getDual = 7}
instance ReviewOneItem (Dual a) where
  type ReviewOneItemElement (Dual a) = a

  reviewOneItem =
    _Wrapped
  {-# INLINE reviewOneItem #-}

-- | >>> review reviewOneItem 7 :: Down Int
-- Down 7
instance ReviewOneItem (Down a) where
  type ReviewOneItemElement (Down a) = a

  reviewOneItem =
    _Wrapped
  {-# INLINE reviewOneItem #-}

-- | >>> review reviewOneItem 7 :: Sum Int
-- Sum {getSum = 7}
instance ReviewOneItem (Sum a) where
  type ReviewOneItemElement (Sum a) = a

  reviewOneItem =
    _Wrapped
  {-# INLINE reviewOneItem #-}

-- | >>> review reviewOneItem 7 :: Product Int
-- Product {getProduct = 7}
instance ReviewOneItem (Product a) where
  type ReviewOneItemElement (Product a) = a

  reviewOneItem =
    _Wrapped
  {-# INLINE reviewOneItem #-}

-- | >>> review reviewOneItem 7 :: Min Int
-- Min {getMin = 7}
instance ReviewOneItem (Min a) where
  type ReviewOneItemElement (Min a) = a

  reviewOneItem =
    _Wrapped
  {-# INLINE reviewOneItem #-}

-- | >>> review reviewOneItem 7 :: Max Int
-- Max {getMax = 7}
instance ReviewOneItem (Max a) where
  type ReviewOneItemElement (Max a) = a

  reviewOneItem =
    _Wrapped
  {-# INLINE reviewOneItem #-}

-- | >>> review reviewOneItem 7 :: ZipList Int
-- ZipList {getZipList = [7]}
instance ReviewOneItem (ZipList a) where
  type ReviewOneItemElement (ZipList a) = a

  reviewOneItem =
    _Wrapped . reviewOneItem
  {-# INLINE reviewOneItem #-}

-- | >>> review reviewOneItem 7 :: Par1 Int
-- Par1 {unPar1 = 7}
instance ReviewOneItem (Par1 a) where
  type ReviewOneItemElement (Par1 a) = a

  reviewOneItem =
    _Wrapped
  {-# INLINE reviewOneItem #-}

-- | >>> review reviewOneItem 7 :: Solo Int
-- MkSolo 7
instance ReviewOneItem (Solo a) where
  type ReviewOneItemElement (Solo a) = a

  reviewOneItem =
    unto
      MkSolo
  {-# INLINE reviewOneItem #-}