ac-library-hs-1.2.2.0: src/AtCoder/Extra/Monoid/V2.hs
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE TypeFamilies #-}
-- | A monoid acted on by `Mat2x2` or `Affine1`, an affine transformation target.
--
-- ==== As an `Affine1` action target
-- Compared to `Sum`, `V2` hold the length in the second value.
--
-- @since 1.1.0.0
module AtCoder.Extra.Monoid.V2
( -- * V2
V2 (..),
V2Repr,
-- * Constructors
new,
unV2,
zero,
isZero,
)
where
import Data.Vector.Generic qualified as VG
import Data.Vector.Generic.Mutable qualified as VGM
import Data.Vector.Unboxed qualified as VU
import Data.Vector.Unboxed.Mutable qualified as VUM
-- | A monoid acted on by `Mat2x2`, an affine transformation target.
--
-- @since 1.1.0.0
newtype V2 a = V2 (V2Repr a)
deriving newtype
( -- | @since 1.1.0.0
Eq,
-- | @since 1.1.0.0
Ord,
-- | @since 1.1.0.0
Show
)
-- | `V2` internal representation. Tuples are not the fastest representation, but it's easier
-- to implement `Data.Vector.Unboxed.Unbox`.
--
-- @since 1.1.0.0
type V2Repr a = (a, a)
-- | \(O(1)\) Creates a `V2` of length \(1\).
--
-- @since 1.1.0.0
{-# INLINE new #-}
new :: (Num a) => a -> V2 a
new !a = V2 (a, 1)
-- | \(O(1)\) Creates a `V2` of length \(0\), i.e., `mempty`. Note that this value does not change
-- on affine transformation.
--
-- @since 1.2.2.0
{-# INLINE zero #-}
zero :: (Num a) => V2 a
zero = V2 (0, 0)
-- | \(O(1)\) Retrieves the value of `V2`, discarding the length information.
--
-- @since 1.1.0.0
{-# INLINE unV2 #-}
unV2 :: V2 a -> a
unV2 (V2 (!a, !_)) = a
-- | \(O(1)\) Returns whether the `V2` is equal to `zero`
--
-- @since 1.2.2.0
{-# INLINE isZero #-}
isZero :: (Num a, Eq a) => V2 a -> Bool
isZero = (== zero)
-- | @since 1.1.0.0
instance (Num a) => Semigroup (V2 a) where
{-# INLINE (<>) #-}
(V2 (!a1, !a2)) <> (V2 (!b1, !b2)) = V2 (a', b')
where
!a' = a1 + b1
!b' = a2 + b2
-- | @since 1.1.0.0
instance (Num a) => Monoid (V2 a) where
{-# INLINE mempty #-}
mempty = V2 (0, 0)
-- | @since 1.1.0.0
newtype instance VU.MVector s (V2 a) = MV_V2 (VU.MVector s (V2Repr a))
-- | @since 1.1.0.0
newtype instance VU.Vector (V2 a) = V_V2 (VU.Vector (V2Repr a))
-- | @since 1.1.0.0
deriving instance (VU.Unbox a) => VGM.MVector VUM.MVector (V2 a)
-- | @since 1.1.0.0
deriving instance (VU.Unbox a) => VG.Vector VU.Vector (V2 a)
-- | @since 1.1.0.0
instance (VU.Unbox a) => VU.Unbox (V2 a)