associative-0.0.1: examples/Data/Associative/Examples/SemigroupOpExamples.hs
{-# OPTIONS_GHC -Wall -Werror #-}
-- |
-- Example usages of "Data.Associative.SemigroupOp".
module Data.Associative.Examples.SemigroupOpExamples
( -- * Constructing and running total semigroup operations
add,
cat,
-- * Combining operations with Semigroup (pointwise)
pointwiseExample,
-- * Functor and Profunctor
fmapTotalExample,
lmapExample,
-- * Using effects (monad transformer)
statefulConcat,
)
where
import Control.Monad.State (State, get, put)
import Data.Associative.SemigroupOp
( SemigroupOp',
SemigroupOpT (..),
op,
runSemigroupOp,
runSemigroupOpT,
)
import Data.Functor.Identity (Identity (..))
-- $setup
-- >>> import Data.Functor.Identity (Identity(..))
-- >>> import Data.Profunctor (lmap, rmap)
-- >>> import Control.Monad.State (runState)
-- * Constructing and running total semigroup operations
-- | A total semigroup operation for addition.
--
-- >>> runSemigroupOp add 3 4
-- 7
add :: SemigroupOp' Int
add = op (+)
-- | A total semigroup operation for list concatenation.
--
-- >>> runSemigroupOp cat [1,2] [3,4 :: Int]
-- [1,2,3,4]
cat :: SemigroupOp' [Int]
cat = op (++)
-- * Combining operations with Semigroup (pointwise)
-- | Total semigroup operations combine pointwise: both operations
-- run and their results are combined via the inner 'Semigroup'.
--
-- >>> runSemigroupOp (cat <> cat) [1] [2 :: Int]
-- [1,2,1,2]
pointwiseExample :: SemigroupOp' [Int]
pointwiseExample = cat <> cat
-- * Functor and Profunctor
-- | 'fmap' transforms the result of a total operation.
--
-- >>> runSemigroupOpT (fmap show add) 3 4
-- Identity "7"
fmapTotalExample :: SemigroupOpT Identity Int String
fmapTotalExample = fmap show add
-- | 'lmap' transforms the inputs (contravariantly).
--
-- >>> runSemigroupOp (lmap negate add) (-3) (-4)
-- 7
--
-- 'rmap' transforms the output (same as 'fmap').
--
-- >>> runSemigroupOp (rmap (*10) add) 3 4
-- 70
lmapExample :: SemigroupOp' Int
lmapExample = fmap (* 10) add
-- * Using effects (monad transformer)
-- | A total semigroup operation with state.
--
-- >>> runState (runSemigroupOpT statefulConcat "hello" " world") 0
-- ("hello world",1)
statefulConcat :: SemigroupOpT (State Int) String String
statefulConcat =
SemigroupOpT
( \a b -> do
n <- get
put (n + 1)
pure (a ++ b)
)
-- helpers to suppress unused-import warnings for re-exports used in doctests
_suppressRunSemigroupOp :: SemigroupOp' a -> a -> a -> a
_suppressRunSemigroupOp = runSemigroupOp
_suppressRunSemigroupOpT :: SemigroupOpT f a b -> a -> a -> f b
_suppressRunSemigroupOpT = runSemigroupOpT