diff --git a/associative.cabal b/associative.cabal
--- a/associative.cabal
+++ b/associative.cabal
@@ -1,6 +1,6 @@
 cabal-version:        2.4
 name:                 associative
-version:              0.0.1
+version:              0.0.2
 synopsis:             Partial Semigroup and Semigroup operations
 description:          Partial Semigroup and Semigroup operations: Associative, Closed, Binary operation which may not be defined for all domains
 license:              BSD-3-Clause
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,10 @@
+0.0.2
+
+* Wrapper values (`semigroupMaybe`, `semigroupDual`, `semigroupDown`, `semigroupIdentity`, `semigroupTuple`, `semigroupWrappedMonoid`, `semigroupFunction`, and their `psemigroup`/`monoid`/`pmonoid` counterparts) now take an explicit `SemigroupOp'` or `MonoidOp` parameter instead of using `Semigroup`/`Monoid` class constraints
+* New `Apply` sequencing values: `semigroupApplyThen`, `semigroupApplyFirst`, `psemigroupApplyThen`, `psemigroupApplyFirst`
+* New `Applicative` sequencing values: `semigroupApplicativeThen`, `semigroupApplicativeFirst`, `psemigroupApplicativeThen`, `psemigroupApplicativeFirst`
+* New functor-lifting combinators: `semigroupLiftF2`, `semigroupLiftA2`, `psemigroupLiftF2`, `psemigroupLiftA2`, `monoidLiftF2`, `monoidLiftA2`, `pmonoidLiftF2`, `pmonoidLiftA2`
+
 0.0.1
 
 * This change log starts
diff --git a/src/Data/Associative/MonoidOp.hs b/src/Data/Associative/MonoidOp.hs
--- a/src/Data/Associative/MonoidOp.hs
+++ b/src/Data/Associative/MonoidOp.hs
@@ -44,6 +44,8 @@
     monoidFunction,
     monoidAlt,
     monoidAlternative,
+    monoidLiftF2,
+    monoidLiftA2,
 
     -- * Values (via MonoidOp)
     monoidMin,
@@ -76,7 +78,7 @@
     iso,
     lens,
   )
-import Data.Associative.SemigroupOp (HasSemigroupOpT (..), SemigroupOp', op, runSemigroupOp)
+import Data.Associative.SemigroupOp (HasSemigroupOpT (..), SemigroupOp', op, runSemigroupOp, semigroupDual, semigroupDown, semigroupFunction, semigroupIdentity, semigroupLiftA2, semigroupMaybe, semigroupTuple, semigroupWrappedMonoid)
 import qualified Data.Associative.SemigroupOp as SG (semigroupSemigroup)
 import Data.Bits (Bits, FiniteBits, complement, xor, zeroBits, (.&.), (.|.))
 import Data.Functor.Alt (Alt (..))
@@ -100,7 +102,7 @@
 import GHC.Generics (Generic)
 
 -- $setup
--- >>> import Data.Associative.SemigroupOp (SemigroupOpT(..), op)
+-- >>> import Data.Associative.SemigroupOp (SemigroupOpT(..), SemigroupOp', op, semigroupList)
 -- >>> import Control.Lens (view, review)
 -- >>> import Data.Functor.Identity (Identity(..))
 -- >>> import Data.Ord (Down(..))
@@ -273,60 +275,60 @@
 
 -- | 'Nothing' is identity; 'Just' values are combined.
 --
--- >>> run monoidMaybe (Just [1]) (Just [2 :: Int])
+-- >>> run (monoidMaybe semigroupList) (Just [1]) (Just [2 :: Int])
 -- Just [1,2]
--- >>> run monoidMaybe Nothing (Just [2 :: Int])
+-- >>> run (monoidMaybe semigroupList) Nothing (Just [2 :: Int])
 -- Just [2]
--- >>> identityMonoidOp monoidMaybe
+-- >>> identityMonoidOp (monoidMaybe semigroupList)
 -- Nothing
-monoidMaybe :: (Semigroup a) => MonoidOp (Maybe a)
-monoidMaybe = monoid
+monoidMaybe :: SemigroupOp' a -> MonoidOp (Maybe a)
+monoidMaybe s = MonoidOp (semigroupMaybe s) Nothing
 
 -- | Reverses the inner monoid.
 --
--- >>> run monoidDual (Dual [1]) (Dual [2 :: Int])
+-- >>> run (monoidDual monoidList) (Dual [1]) (Dual [2 :: Int])
 -- Dual {getDual = [2,1]}
--- >>> identityMonoidOp (monoidDual :: MonoidOp (Dual [Int]))
+-- >>> identityMonoidOp (monoidDual (monoidList :: MonoidOp [Int]))
 -- Dual {getDual = []}
-monoidDual :: (Monoid a) => MonoidOp (Dual a)
-monoidDual = monoid
+monoidDual :: MonoidOp a -> MonoidOp (Dual a)
+monoidDual (MonoidOp s e) = MonoidOp (semigroupDual s) (Dual e)
 
 -- | Delegates through 'Down'.
 --
--- >>> run monoidDown (Down [1]) (Down [2 :: Int])
+-- >>> run (monoidDown monoidList) (Down [1]) (Down [2 :: Int])
 -- Down [1,2]
-monoidDown :: (Monoid a) => MonoidOp (Down a)
-monoidDown = monoid
+monoidDown :: MonoidOp a -> MonoidOp (Down a)
+monoidDown (MonoidOp s e) = MonoidOp (semigroupDown s) (Down e)
 
 -- | Delegates through 'Identity'.
 --
--- >>> run monoidIdentity (Identity [1]) (Identity [2 :: Int])
+-- >>> run (monoidIdentity monoidList) (Identity [1]) (Identity [2 :: Int])
 -- Identity [1,2]
-monoidIdentity :: (Monoid a) => MonoidOp (Identity a)
-monoidIdentity = monoid
+monoidIdentity :: MonoidOp a -> MonoidOp (Identity a)
+monoidIdentity (MonoidOp s e) = MonoidOp (semigroupIdentity s) (Identity e)
 
 -- | Pairwise combination.
 --
--- >>> run monoidTuple ([1 :: Int], [10]) ([2], [20 :: Int])
+-- >>> run (monoidTuple monoidList monoidList) ([1 :: Int], [10]) ([2], [20 :: Int])
 -- ([1,2],[10,20])
--- >>> identityMonoidOp (monoidTuple :: MonoidOp ([Int], [Int]))
+-- >>> identityMonoidOp (monoidTuple monoidList monoidList :: MonoidOp ([Int], [Int]))
 -- ([],[])
-monoidTuple :: (Monoid a, Monoid b) => MonoidOp (a, b)
-monoidTuple = monoid
+monoidTuple :: MonoidOp a -> MonoidOp b -> MonoidOp (a, b)
+monoidTuple (MonoidOp sa ea) (MonoidOp sb eb) = MonoidOp (semigroupTuple sa sb) (ea, eb)
 
--- | Uses the underlying 'Monoid' operation.
+-- | Uses the underlying monoid operation.
 --
--- >>> run monoidWrappedMonoid (WrapMonoid [1]) (WrapMonoid [2 :: Int])
+-- >>> run (monoidWrappedMonoid monoidList) (WrapMonoid [1]) (WrapMonoid [2 :: Int])
 -- WrapMonoid {unwrapMonoid = [1,2]}
-monoidWrappedMonoid :: (Monoid a) => MonoidOp (WrappedMonoid a)
-monoidWrappedMonoid = monoid
+monoidWrappedMonoid :: MonoidOp a -> MonoidOp (WrappedMonoid a)
+monoidWrappedMonoid (MonoidOp s e) = MonoidOp (semigroupWrappedMonoid s) (WrapMonoid e)
 
 -- | Pointwise combination.
 --
--- >>> run monoidFunction (++ "a") ((++ "b") :: String -> String) "x"
+-- >>> run (monoidFunction monoidList) (++ "a") ((++ "b") :: String -> String) "x"
 -- "xaxb"
-monoidFunction :: (Monoid b) => MonoidOp (a -> b)
-monoidFunction = monoid
+monoidFunction :: MonoidOp b -> MonoidOp (a -> b)
+monoidFunction (MonoidOp s e) = MonoidOp (semigroupFunction s) (const e)
 
 -- | First-success on 'Maybe' via 'Alt'.
 --
@@ -349,6 +351,25 @@
 -- Nothing
 monoidAlternative :: MonoidOp (Maybe a)
 monoidAlternative = MonoidOp (op (<|>)) Nothing
+
+-- | Lift a monoid operation through an 'Data.Functor.Apply.Apply' functor via 'Data.Functor.Apply.liftF2'.
+-- Requires 'Applicative' for 'pure' to construct the identity element.
+--
+-- >>> run (monoidLiftF2 add) (Just 3) (Just 4 :: Maybe Int)
+-- Just 7
+-- >>> identityMonoidOp (monoidLiftF2 add :: MonoidOp (Maybe Int))
+-- Just 0
+monoidLiftF2 :: (Applicative f) => MonoidOp a -> MonoidOp (f a)
+monoidLiftF2 (MonoidOp s e) = MonoidOp (semigroupLiftA2 s) (pure e)
+
+-- | Lift a monoid operation through an 'Applicative' functor via 'Control.Applicative.liftA2'.
+--
+-- >>> run (monoidLiftA2 add) (Just 3) (Just 4 :: Maybe Int)
+-- Just 7
+-- >>> identityMonoidOp (monoidLiftA2 add :: MonoidOp (Maybe Int))
+-- Just 0
+monoidLiftA2 :: (Applicative f) => MonoidOp a -> MonoidOp (f a)
+monoidLiftA2 (MonoidOp s e) = MonoidOp (semigroupLiftA2 s) (pure e)
 
 ----
 -- MonoidOp values via MonoidOp constructor
diff --git a/src/Data/Associative/PartialMonoidOp.hs b/src/Data/Associative/PartialMonoidOp.hs
--- a/src/Data/Associative/PartialMonoidOp.hs
+++ b/src/Data/Associative/PartialMonoidOp.hs
@@ -44,6 +44,8 @@
     pmonoidFunction,
     pmonoidAlt,
     pmonoidAlternative,
+    pmonoidLiftF2,
+    pmonoidLiftA2,
 
     -- * Values (via PartialMonoidOp)
     pmonoidMin,
@@ -77,14 +79,24 @@
     lens,
     review,
   )
+import Data.Associative.MonoidOp (MonoidOp (..))
 import Data.Associative.PartialSemigroupOp
   ( HasPartialSemigroupOpT (..),
     PartialSemigroupOp',
     iPartialSemigroupOp,
+    psemigroupDown,
+    psemigroupDual,
+    psemigroupFunction,
+    psemigroupIdentity,
+    psemigroupLiftA2,
+    psemigroupMaybe,
+    psemigroupTuple,
+    psemigroupWrappedMonoid,
     runPartialSemigroupOp,
     psemigroupSemigroup,
     total,
   )
+import Data.Associative.SemigroupOp (SemigroupOp')
 import Data.Bits (Bits, FiniteBits, complement, xor, zeroBits, (.&.), (.|.))
 import Data.Functor.Alt (Alt (..))
 import Data.Functor.Identity (Identity (..))
@@ -107,6 +119,8 @@
 import GHC.Generics (Generic)
 
 -- $setup
+-- >>> import Data.Associative.SemigroupOp (SemigroupOp', op, semigroupList)
+-- >>> import Data.Associative.MonoidOp (MonoidOp(..), monoidList)
 -- >>> import Data.Associative.PartialSemigroupOp (PartialSemigroupOpT(..), total)
 -- >>> import Control.Lens (view, review)
 -- >>> import Data.Functor.Identity (Identity(..))
@@ -289,60 +303,60 @@
 
 -- | 'Nothing' is identity; 'Just' values are combined.
 --
--- >>> run pmonoidMaybe (Just [1]) (Just [2 :: Int])
+-- >>> run (pmonoidMaybe semigroupList) (Just [1]) (Just [2 :: Int])
 -- Just (Just [1,2])
--- >>> run pmonoidMaybe Nothing (Just [2 :: Int])
+-- >>> run (pmonoidMaybe semigroupList) Nothing (Just [2 :: Int])
 -- Just (Just [2])
--- >>> identityPartialMonoidOp pmonoidMaybe
+-- >>> identityPartialMonoidOp (pmonoidMaybe semigroupList)
 -- Nothing
-pmonoidMaybe :: (Semigroup a) => PartialMonoidOp (Maybe a)
-pmonoidMaybe = pmonoid
+pmonoidMaybe :: SemigroupOp' a -> PartialMonoidOp (Maybe a)
+pmonoidMaybe s = PartialMonoidOp (psemigroupMaybe s) Nothing
 
 -- | Reverses the inner monoid.
 --
--- >>> run pmonoidDual (Dual [1]) (Dual [2 :: Int])
+-- >>> run (pmonoidDual monoidList) (Dual [1]) (Dual [2 :: Int])
 -- Just (Dual {getDual = [2,1]})
--- >>> identityPartialMonoidOp (pmonoidDual :: PartialMonoidOp (Dual [Int]))
+-- >>> identityPartialMonoidOp (pmonoidDual (monoidList :: MonoidOp [Int]))
 -- Dual {getDual = []}
-pmonoidDual :: (Monoid a) => PartialMonoidOp (Dual a)
-pmonoidDual = pmonoid
+pmonoidDual :: MonoidOp a -> PartialMonoidOp (Dual a)
+pmonoidDual (MonoidOp s e) = PartialMonoidOp (psemigroupDual s) (Dual e)
 
 -- | Delegates through 'Down'.
 --
--- >>> run pmonoidDown (Down [1]) (Down [2 :: Int])
+-- >>> run (pmonoidDown monoidList) (Down [1]) (Down [2 :: Int])
 -- Just (Down [1,2])
-pmonoidDown :: (Monoid a) => PartialMonoidOp (Down a)
-pmonoidDown = pmonoid
+pmonoidDown :: MonoidOp a -> PartialMonoidOp (Down a)
+pmonoidDown (MonoidOp s e) = PartialMonoidOp (psemigroupDown s) (Down e)
 
 -- | Delegates through 'Identity'.
 --
--- >>> run pmonoidIdentity (Identity [1]) (Identity [2 :: Int])
+-- >>> run (pmonoidIdentity monoidList) (Identity [1]) (Identity [2 :: Int])
 -- Just (Identity [1,2])
-pmonoidIdentity :: (Monoid a) => PartialMonoidOp (Identity a)
-pmonoidIdentity = pmonoid
+pmonoidIdentity :: MonoidOp a -> PartialMonoidOp (Identity a)
+pmonoidIdentity (MonoidOp s e) = PartialMonoidOp (psemigroupIdentity s) (Identity e)
 
 -- | Pairwise combination.
 --
--- >>> run pmonoidTuple ([1 :: Int], [10]) ([2], [20 :: Int])
+-- >>> run (pmonoidTuple monoidList monoidList) ([1 :: Int], [10]) ([2], [20 :: Int])
 -- Just ([1,2],[10,20])
--- >>> identityPartialMonoidOp (pmonoidTuple :: PartialMonoidOp ([Int], [Int]))
+-- >>> identityPartialMonoidOp (pmonoidTuple monoidList monoidList :: PartialMonoidOp ([Int], [Int]))
 -- ([],[])
-pmonoidTuple :: (Monoid a, Monoid b) => PartialMonoidOp (a, b)
-pmonoidTuple = pmonoid
+pmonoidTuple :: MonoidOp a -> MonoidOp b -> PartialMonoidOp (a, b)
+pmonoidTuple (MonoidOp sa ea) (MonoidOp sb eb) = PartialMonoidOp (psemigroupTuple sa sb) (ea, eb)
 
--- | Uses the underlying 'Monoid' operation.
+-- | Uses the underlying monoid operation.
 --
--- >>> run pmonoidWrappedMonoid (WrapMonoid [1]) (WrapMonoid [2 :: Int])
+-- >>> run (pmonoidWrappedMonoid monoidList) (WrapMonoid [1]) (WrapMonoid [2 :: Int])
 -- Just (WrapMonoid {unwrapMonoid = [1,2]})
-pmonoidWrappedMonoid :: (Monoid a) => PartialMonoidOp (WrappedMonoid a)
-pmonoidWrappedMonoid = pmonoid
+pmonoidWrappedMonoid :: MonoidOp a -> PartialMonoidOp (WrappedMonoid a)
+pmonoidWrappedMonoid (MonoidOp s e) = PartialMonoidOp (psemigroupWrappedMonoid s) (WrapMonoid e)
 
 -- | Pointwise combination.
 --
--- >>> fmap ($ "x") (run pmonoidFunction (++ "a") ((++ "b") :: String -> String))
+-- >>> fmap ($ "x") (run (pmonoidFunction monoidList) (++ "a") ((++ "b") :: String -> String))
 -- Just "xaxb"
-pmonoidFunction :: (Monoid b) => PartialMonoidOp (a -> b)
-pmonoidFunction = pmonoid
+pmonoidFunction :: MonoidOp b -> PartialMonoidOp (a -> b)
+pmonoidFunction (MonoidOp s e) = PartialMonoidOp (psemigroupFunction s) (const e)
 
 -- | First-success on 'Maybe' via 'Alt'.
 --
@@ -365,6 +379,25 @@
 -- Nothing
 pmonoidAlternative :: PartialMonoidOp (Maybe a)
 pmonoidAlternative = PartialMonoidOp (total (<|>)) Nothing
+
+-- | Lift a monoid operation through an 'Data.Functor.Apply.Apply' functor via 'Data.Functor.Apply.liftF2'.
+-- Requires 'Applicative' for 'pure' to construct the identity element.
+--
+-- >>> run (pmonoidLiftF2 monoidList) (Just [1,2]) (Just [3,4 :: Int])
+-- Just (Just [1,2,3,4])
+-- >>> identityPartialMonoidOp (pmonoidLiftF2 monoidList :: PartialMonoidOp (Maybe [Int]))
+-- Just []
+pmonoidLiftF2 :: (Applicative f) => MonoidOp a -> PartialMonoidOp (f a)
+pmonoidLiftF2 (MonoidOp s e) = PartialMonoidOp (psemigroupLiftA2 s) (pure e)
+
+-- | Lift a monoid operation through an 'Applicative' functor via 'Control.Applicative.liftA2'.
+--
+-- >>> run (pmonoidLiftA2 monoidList) (Just [1,2]) (Just [3,4 :: Int])
+-- Just (Just [1,2,3,4])
+-- >>> identityPartialMonoidOp (pmonoidLiftA2 monoidList :: PartialMonoidOp (Maybe [Int]))
+-- Just []
+pmonoidLiftA2 :: (Applicative f) => MonoidOp a -> PartialMonoidOp (f a)
+pmonoidLiftA2 (MonoidOp s e) = PartialMonoidOp (psemigroupLiftA2 s) (pure e)
 
 ----
 -- PartialMonoidOp values via PartialMonoidOp constructor
diff --git a/src/Data/Associative/PartialSemigroupOp.hs b/src/Data/Associative/PartialSemigroupOp.hs
--- a/src/Data/Associative/PartialSemigroupOp.hs
+++ b/src/Data/Associative/PartialSemigroupOp.hs
@@ -66,6 +66,12 @@
     psemigroupFunction,
     psemigroupAlt,
     psemigroupAlternative,
+    psemigroupApplyThen,
+    psemigroupApplyFirst,
+    psemigroupApplicativeThen,
+    psemigroupApplicativeFirst,
+    psemigroupLiftF2,
+    psemigroupLiftA2,
 
     -- * Values (via total)
     psemigroupFirst,
@@ -121,7 +127,7 @@
 import Control.Selective (Selective (..), selectM)
 import Data.Bits (Bits, FiniteBits, complement, xor, (.&.), (.|.))
 import Data.Functor.Alt (Alt (..))
-import Data.Functor.Apply (Apply (..))
+import Data.Functor.Apply (Apply (..), liftF2)
 import Data.Functor.Bind (Bind (..))
 import Data.Functor.Extend (Extend (..))
 import Data.Functor.Identity (Identity (..))
@@ -138,10 +144,11 @@
 import Data.List.NonEmpty (NonEmpty)
 import Data.Map (Map)
 import qualified Data.Map as Map
-import Data.Ord (Down)
+import Data.Ord (Down (..))
 import Data.Profunctor (Choice (..), Profunctor (..), Strong (..))
 import Data.Proxy (Proxy)
-import Data.Semigroup (Dual, WrappedMonoid)
+import Data.Semigroup (Dual (..), WrappedMonoid (..))
+import Data.Associative.SemigroupOp (SemigroupOp', runSemigroupOp)
 import Data.Semigroupoid (Semigroupoid (..))
 import Data.Set (Set)
 import qualified Data.Set as Set
@@ -171,9 +178,11 @@
 -- >>> import qualified Data.Map as Map
 -- >>> import qualified Data.IntMap as IntMap
 -- >>> import qualified Data.HashMap.Strict as HashMap
+-- >>> import Data.Associative.SemigroupOp (SemigroupOp', op, semigroupList)
 -- >>> import Data.List (sort)
 -- >>> let addPos = PartialSemigroupOpT (\a b -> Identity (if a > 0 && b > 0 then Just (a + b) else Nothing)) :: PartialSemigroupOp' Int
 -- >>> let total = PartialSemigroupOpT (\a b -> Identity (Just (a + b))) :: PartialSemigroupOp' Int
+-- >>> let cat = op (++) :: SemigroupOp' [Int]
 -- >>> let run = runPartialSemigroupOp
 
 -- | A partial semigroup transformer. The wrapped operation must be associative
@@ -715,56 +724,59 @@
 
 -- | 'Nothing' is identity; 'Just' values are combined.
 --
--- >>> run psemigroupMaybe (Just [1]) (Just [2 :: Int])
+-- >>> run (psemigroupMaybe cat) (Just [1]) (Just [2 :: Int])
 -- Just (Just [1,2])
--- >>> run psemigroupMaybe Nothing (Just [2 :: Int])
+-- >>> run (psemigroupMaybe cat) Nothing (Just [2 :: Int])
 -- Just (Just [2])
--- >>> run psemigroupMaybe (Just [1 :: Int]) Nothing
+-- >>> run (psemigroupMaybe cat) (Just [1 :: Int]) Nothing
 -- Just (Just [1])
-psemigroupMaybe :: (Semigroup a) => PartialSemigroupOp' (Maybe a)
-psemigroupMaybe = psemigroupSemigroup
+psemigroupMaybe :: SemigroupOp' a -> PartialSemigroupOp' (Maybe a)
+psemigroupMaybe s = total (\mx my -> case (mx, my) of
+  (Nothing, y) -> y
+  (x, Nothing) -> x
+  (Just x, Just y) -> Just (runSemigroupOp s x y))
 
 -- | Reverses the inner semigroup.
 --
--- >>> run psemigroupDual (Dual [1]) (Dual [2 :: Int])
+-- >>> run (psemigroupDual cat) (Dual [1]) (Dual [2 :: Int])
 -- Just (Dual {getDual = [2,1]})
-psemigroupDual :: (Semigroup a) => PartialSemigroupOp' (Dual a)
-psemigroupDual = psemigroupSemigroup
+psemigroupDual :: SemigroupOp' a -> PartialSemigroupOp' (Dual a)
+psemigroupDual s = total (\(Dual x) (Dual y) -> Dual (runSemigroupOp s y x))
 
 -- | Delegates through 'Down'.
 --
--- >>> run psemigroupDown (Down [1]) (Down [2 :: Int])
+-- >>> run (psemigroupDown cat) (Down [1]) (Down [2 :: Int])
 -- Just (Down [1,2])
-psemigroupDown :: (Semigroup a) => PartialSemigroupOp' (Down a)
-psemigroupDown = psemigroupSemigroup
+psemigroupDown :: SemigroupOp' a -> PartialSemigroupOp' (Down a)
+psemigroupDown s = total (\(Down x) (Down y) -> Down (runSemigroupOp s x y))
 
 -- | Delegates through 'Identity'.
 --
--- >>> run psemigroupIdentity (Identity [1]) (Identity [2 :: Int])
+-- >>> run (psemigroupIdentity cat) (Identity [1]) (Identity [2 :: Int])
 -- Just (Identity [1,2])
-psemigroupIdentity :: (Semigroup a) => PartialSemigroupOp' (Identity a)
-psemigroupIdentity = psemigroupSemigroup
+psemigroupIdentity :: SemigroupOp' a -> PartialSemigroupOp' (Identity a)
+psemigroupIdentity s = total (\(Identity x) (Identity y) -> Identity (runSemigroupOp s x y))
 
 -- | Pairwise combination.
 --
--- >>> run psemigroupTuple ([1 :: Int], [10]) ([2], [20 :: Int])
+-- >>> run (psemigroupTuple cat cat) ([1 :: Int], [10]) ([2], [20 :: Int])
 -- Just ([1,2],[10,20])
-psemigroupTuple :: (Semigroup a, Semigroup b) => PartialSemigroupOp' (a, b)
-psemigroupTuple = psemigroupSemigroup
+psemigroupTuple :: SemigroupOp' a -> SemigroupOp' b -> PartialSemigroupOp' (a, b)
+psemigroupTuple sa sb = total (\(a1, b1) (a2, b2) -> (runSemigroupOp sa a1 a2, runSemigroupOp sb b1 b2))
 
--- | Uses the underlying 'Monoid' operation.
+-- | Uses the underlying semigroup operation.
 --
--- >>> run psemigroupWrappedMonoid (WrapMonoid [1]) (WrapMonoid [2 :: Int])
+-- >>> run (psemigroupWrappedMonoid cat) (WrapMonoid [1]) (WrapMonoid [2 :: Int])
 -- Just (WrapMonoid {unwrapMonoid = [1,2]})
-psemigroupWrappedMonoid :: (Monoid a) => PartialSemigroupOp' (WrappedMonoid a)
-psemigroupWrappedMonoid = psemigroupSemigroup
+psemigroupWrappedMonoid :: SemigroupOp' a -> PartialSemigroupOp' (WrappedMonoid a)
+psemigroupWrappedMonoid s = total (\(WrapMonoid x) (WrapMonoid y) -> WrapMonoid (runSemigroupOp s x y))
 
 -- | Pointwise combination.
 --
--- >>> fmap ($ "x") (run psemigroupFunction (++ "a") ((++ "b") :: String -> String))
+-- >>> fmap ($ "x") (run (psemigroupFunction semigroupList) (++ "a") ((++ "b") :: String -> String))
 -- Just "xaxb"
-psemigroupFunction :: (Semigroup b) => PartialSemigroupOp' (a -> b)
-psemigroupFunction = psemigroupSemigroup
+psemigroupFunction :: SemigroupOp' b -> PartialSemigroupOp' (a -> b)
+psemigroupFunction s = total (\f g x -> runSemigroupOp s (f x) (g x))
 
 -- | First-success on 'Maybe' via 'Alt'.
 --
@@ -783,6 +795,60 @@
 -- Just (Just 2)
 psemigroupAlternative :: PartialSemigroupOp' (Maybe a)
 psemigroupAlternative = total (<|>)
+
+-- | Sequence both, keep last result via 'Data.Functor.Apply.Apply'.
+--
+-- >>> run psemigroupApplyThen (Just 1) (Just 2 :: Maybe Int)
+-- Just (Just 2)
+-- >>> run psemigroupApplyThen Nothing (Just 2 :: Maybe Int)
+-- Just Nothing
+psemigroupApplyThen :: (Apply f) => PartialSemigroupOp' (f a)
+psemigroupApplyThen = total (.>)
+
+-- | Sequence both, keep first result via 'Data.Functor.Apply.Apply'.
+--
+-- >>> run psemigroupApplyFirst (Just 1) (Just 2 :: Maybe Int)
+-- Just (Just 1)
+-- >>> run psemigroupApplyFirst Nothing (Just 2 :: Maybe Int)
+-- Just Nothing
+psemigroupApplyFirst :: (Apply f) => PartialSemigroupOp' (f a)
+psemigroupApplyFirst = total (<.)
+
+-- | Sequence both, keep last result via 'Applicative'.
+--
+-- >>> run psemigroupApplicativeThen (Just 1) (Just 2 :: Maybe Int)
+-- Just (Just 2)
+-- >>> run psemigroupApplicativeThen Nothing (Just 2 :: Maybe Int)
+-- Just Nothing
+psemigroupApplicativeThen :: (Applicative f) => PartialSemigroupOp' (f a)
+psemigroupApplicativeThen = total (*>)
+
+-- | Sequence both, keep first result via 'Applicative'.
+--
+-- >>> run psemigroupApplicativeFirst (Just 1) (Just 2 :: Maybe Int)
+-- Just (Just 1)
+-- >>> run psemigroupApplicativeFirst Nothing (Just 2 :: Maybe Int)
+-- Just Nothing
+psemigroupApplicativeFirst :: (Applicative f) => PartialSemigroupOp' (f a)
+psemigroupApplicativeFirst = total (<*)
+
+-- | Lift a semigroup operation through an 'Data.Functor.Apply.Apply' functor via 'Data.Functor.Apply.liftF2'.
+--
+-- >>> run (psemigroupLiftF2 (op (+) :: SemigroupOp' Int)) (Just 3) (Just 4)
+-- Just (Just 7)
+-- >>> run (psemigroupLiftF2 (op (+) :: SemigroupOp' Int)) Nothing (Just 4)
+-- Just Nothing
+psemigroupLiftF2 :: (Apply f) => SemigroupOp' a -> PartialSemigroupOp' (f a)
+psemigroupLiftF2 s = total (liftF2 (runSemigroupOp s))
+
+-- | Lift a semigroup operation through an 'Applicative' functor via 'Control.Applicative.liftA2'.
+--
+-- >>> run (psemigroupLiftA2 (op (+) :: SemigroupOp' Int)) (Just 3) (Just 4)
+-- Just (Just 7)
+-- >>> run (psemigroupLiftA2 (op (+) :: SemigroupOp' Int)) Nothing (Just 4)
+-- Just Nothing
+psemigroupLiftA2 :: (Applicative f) => SemigroupOp' a -> PartialSemigroupOp' (f a)
+psemigroupLiftA2 s = total (liftA2 (runSemigroupOp s))
 
 ----
 -- PartialSemigroupOp' values via total
diff --git a/src/Data/Associative/SemigroupOp.hs b/src/Data/Associative/SemigroupOp.hs
--- a/src/Data/Associative/SemigroupOp.hs
+++ b/src/Data/Associative/SemigroupOp.hs
@@ -61,6 +61,12 @@
     semigroupFunction,
     semigroupAlt,
     semigroupAlternative,
+    semigroupApplyThen,
+    semigroupApplyFirst,
+    semigroupApplicativeThen,
+    semigroupApplicativeFirst,
+    semigroupLiftF2,
+    semigroupLiftA2,
 
     -- * Values (via op)
     semigroupFirst,
@@ -115,7 +121,7 @@
 import Control.Selective (Selective (..), selectM)
 import Data.Bits (Bits, FiniteBits, complement, xor, (.&.), (.|.))
 import Data.Functor.Alt (Alt (..))
-import Data.Functor.Apply (Apply (..))
+import Data.Functor.Apply (Apply (..), liftF2)
 import Data.Functor.Bind (Bind (..))
 import Data.Functor.Extend (Extend (..))
 import Data.Functor.Identity (Identity (..))
@@ -132,10 +138,10 @@
 import Data.List.NonEmpty (NonEmpty)
 import Data.Map (Map)
 import qualified Data.Map as Map
-import Data.Ord (Down)
+import Data.Ord (Down (..))
 import Data.Profunctor (Choice (..), Profunctor (..), Strong (..))
 import Data.Proxy (Proxy)
-import Data.Semigroup (Dual, WrappedMonoid)
+import Data.Semigroup (Dual (..), WrappedMonoid (..))
 import Data.Semigroupoid (Semigroupoid (..))
 import Data.Set (Set)
 import qualified Data.Set as Set
@@ -608,14 +614,17 @@
 
 -- | 'Nothing' is identity; 'Just' values are combined.
 --
--- >>> run semigroupMaybe (Just [1]) (Just [2 :: Int])
+-- >>> run (semigroupMaybe cat) (Just [1]) (Just [2 :: Int])
 -- Just [1,2]
--- >>> run semigroupMaybe Nothing (Just [2 :: Int])
+-- >>> run (semigroupMaybe cat) Nothing (Just [2 :: Int])
 -- Just [2]
--- >>> run semigroupMaybe (Just [1 :: Int]) Nothing
+-- >>> run (semigroupMaybe cat) (Just [1 :: Int]) Nothing
 -- Just [1]
-semigroupMaybe :: (Semigroup a) => SemigroupOp' (Maybe a)
-semigroupMaybe = semigroupSemigroup
+semigroupMaybe :: SemigroupOp' a -> SemigroupOp' (Maybe a)
+semigroupMaybe s = op (\mx my -> case (mx, my) of
+  (Nothing, y) -> y
+  (x, Nothing) -> x
+  (Just x, Just y) -> Just (runSemigroupOp s x y))
 
 -- | First-success on 'Maybe' via 'Alt'.
 --
@@ -635,47 +644,101 @@
 semigroupAlternative :: SemigroupOp' (Maybe a)
 semigroupAlternative = op (<|>)
 
+-- | Sequence both, keep last result via 'Data.Functor.Apply.Apply'.
+--
+-- >>> run semigroupApplyThen (Just 1) (Just 2 :: Maybe Int)
+-- Just 2
+-- >>> run semigroupApplyThen Nothing (Just 2 :: Maybe Int)
+-- Nothing
+semigroupApplyThen :: (Apply f) => SemigroupOp' (f a)
+semigroupApplyThen = op (.>)
+
+-- | Sequence both, keep first result via 'Data.Functor.Apply.Apply'.
+--
+-- >>> run semigroupApplyFirst (Just 1) (Just 2 :: Maybe Int)
+-- Just 1
+-- >>> run semigroupApplyFirst Nothing (Just 2 :: Maybe Int)
+-- Nothing
+semigroupApplyFirst :: (Apply f) => SemigroupOp' (f a)
+semigroupApplyFirst = op (<.)
+
+-- | Sequence both, keep last result via 'Applicative'.
+--
+-- >>> run semigroupApplicativeThen (Just 1) (Just 2 :: Maybe Int)
+-- Just 2
+-- >>> run semigroupApplicativeThen Nothing (Just 2 :: Maybe Int)
+-- Nothing
+semigroupApplicativeThen :: (Applicative f) => SemigroupOp' (f a)
+semigroupApplicativeThen = op (*>)
+
+-- | Sequence both, keep first result via 'Applicative'.
+--
+-- >>> run semigroupApplicativeFirst (Just 1) (Just 2 :: Maybe Int)
+-- Just 1
+-- >>> run semigroupApplicativeFirst Nothing (Just 2 :: Maybe Int)
+-- Nothing
+semigroupApplicativeFirst :: (Applicative f) => SemigroupOp' (f a)
+semigroupApplicativeFirst = op (<*)
+
 -- | Reverses the inner semigroup.
 --
--- >>> run semigroupDual (Dual [1]) (Dual [2 :: Int])
+-- >>> run (semigroupDual cat) (Dual [1]) (Dual [2 :: Int])
 -- Dual {getDual = [2,1]}
-semigroupDual :: (Semigroup a) => SemigroupOp' (Dual a)
-semigroupDual = semigroupSemigroup
+semigroupDual :: SemigroupOp' a -> SemigroupOp' (Dual a)
+semigroupDual s = op (\(Dual x) (Dual y) -> Dual (runSemigroupOp s y x))
 
 -- | Delegates through 'Down'.
 --
--- >>> run semigroupDown (Down [1]) (Down [2 :: Int])
+-- >>> run (semigroupDown cat) (Down [1]) (Down [2 :: Int])
 -- Down [1,2]
-semigroupDown :: (Semigroup a) => SemigroupOp' (Down a)
-semigroupDown = semigroupSemigroup
+semigroupDown :: SemigroupOp' a -> SemigroupOp' (Down a)
+semigroupDown s = op (\(Down x) (Down y) -> Down (runSemigroupOp s x y))
 
 -- | Delegates through 'Identity'.
 --
--- >>> run semigroupIdentity (Identity [1]) (Identity [2 :: Int])
+-- >>> run (semigroupIdentity cat) (Identity [1]) (Identity [2 :: Int])
 -- Identity [1,2]
-semigroupIdentity :: (Semigroup a) => SemigroupOp' (Identity a)
-semigroupIdentity = semigroupSemigroup
+semigroupIdentity :: SemigroupOp' a -> SemigroupOp' (Identity a)
+semigroupIdentity s = op (\(Identity x) (Identity y) -> Identity (runSemigroupOp s x y))
 
 -- | Pairwise combination.
 --
--- >>> run semigroupTuple ([1 :: Int], [10]) ([2], [20 :: Int])
+-- >>> run (semigroupTuple cat cat) ([1 :: Int], [10]) ([2], [20 :: Int])
 -- ([1,2],[10,20])
-semigroupTuple :: (Semigroup a, Semigroup b) => SemigroupOp' (a, b)
-semigroupTuple = semigroupSemigroup
+semigroupTuple :: SemigroupOp' a -> SemigroupOp' b -> SemigroupOp' (a, b)
+semigroupTuple sa sb = op (\(a1, b1) (a2, b2) -> (runSemigroupOp sa a1 a2, runSemigroupOp sb b1 b2))
 
--- | Uses the underlying 'Monoid' operation.
+-- | Uses the underlying semigroup operation.
 --
--- >>> run semigroupWrappedMonoid (WrapMonoid [1]) (WrapMonoid [2 :: Int])
+-- >>> run (semigroupWrappedMonoid cat) (WrapMonoid [1]) (WrapMonoid [2 :: Int])
 -- WrapMonoid {unwrapMonoid = [1,2]}
-semigroupWrappedMonoid :: (Monoid a) => SemigroupOp' (WrappedMonoid a)
-semigroupWrappedMonoid = semigroupSemigroup
+semigroupWrappedMonoid :: SemigroupOp' a -> SemigroupOp' (WrappedMonoid a)
+semigroupWrappedMonoid s = op (\(WrapMonoid x) (WrapMonoid y) -> WrapMonoid (runSemigroupOp s x y))
 
 -- | Pointwise combination.
 --
--- >>> run semigroupFunction (++ "a") ((++ "b") :: String -> String) "x"
+-- >>> run (semigroupFunction semigroupList) (++ "a") ((++ "b") :: String -> String) "x"
 -- "xaxb"
-semigroupFunction :: (Semigroup b) => SemigroupOp' (a -> b)
-semigroupFunction = semigroupSemigroup
+semigroupFunction :: SemigroupOp' b -> SemigroupOp' (a -> b)
+semigroupFunction s = op (\f g x -> runSemigroupOp s (f x) (g x))
+
+-- | Lift a semigroup operation through an 'Data.Functor.Apply.Apply' functor via 'Data.Functor.Apply.liftF2'.
+--
+-- >>> run (semigroupLiftF2 add) (Just 3) (Just 4 :: Maybe Int)
+-- Just 7
+-- >>> run (semigroupLiftF2 add) Nothing (Just 4 :: Maybe Int)
+-- Nothing
+semigroupLiftF2 :: (Apply f) => SemigroupOp' a -> SemigroupOp' (f a)
+semigroupLiftF2 s = op (liftF2 (runSemigroupOp s))
+
+-- | Lift a semigroup operation through an 'Applicative' functor via 'Control.Applicative.liftA2'.
+--
+-- >>> run (semigroupLiftA2 add) (Just 3) (Just 4 :: Maybe Int)
+-- Just 7
+-- >>> run (semigroupLiftA2 add) Nothing (Just 4 :: Maybe Int)
+-- Nothing
+semigroupLiftA2 :: (Applicative f) => SemigroupOp' a -> SemigroupOp' (f a)
+semigroupLiftA2 s = op (liftA2 (runSemigroupOp s))
 
 ----
 -- SemigroupOp' values via op
