diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,13 @@
+# 0.5.4.4
+
+## Added features
+
+* Added the array functions `arrayAppend_`, `arrayPrepend_`, `arrayRemove_`, `arrayReplace_`, `arrayShuffle_`, `arraySample_`, `arrayToString_`, and `arrayToStringWithNull_` (#770)
+
+## Updated dependencies
+
+* Updated the upper bound on `time` to include `time-1.14`
+
 # 0.5.4.3
 
 ## Added features
diff --git a/Database/Beam/Postgres/PgSpecific.hs b/Database/Beam/Postgres/PgSpecific.hs
--- a/Database/Beam/Postgres/PgSpecific.hs
+++ b/Database/Beam/Postgres/PgSpecific.hs
@@ -81,6 +81,9 @@
   , arrayUpper_, arrayLower_
   , arrayUpperUnsafe_, arrayLowerUnsafe_
   , arrayLength_, arrayLengthUnsafe_
+  , arrayAppend_, arrayPrepend_, arrayRemove_
+  , arrayReplace_, arrayShuffle_, arraySample_
+  , arrayToString_, arrayToStringWithNull_
 
   , isSupersetOf_, isSubsetOf_
 
@@ -158,6 +161,7 @@
 
 import           GHC.TypeLits
 import           GHC.Exts hiding (toList)
+import           Data.Text (Text)
 
 -- ** Postgres-specific functions
 
@@ -410,6 +414,165 @@
 QExpr a ++. QExpr b =
   QExpr (pgBinOp "||" <$> a <*> b)
 
+-- | Postgres array_append(value) function.
+--
+-- Appends an element to the end of an array. Equivalent to the
+-- @anycompatiblearray || anycompatible@ operator.
+--
+-- Notes:
+-- - The array must be empty or one-dimensional (per Postgres rules for
+--   concatenating an element with an array).
+-- - If the array is NULL, the result is NULL. If the element is NULL,
+--   a NULL element is appended.
+--
+-- @since 0.5.4.4
+arrayAppend_
+  :: QGenExpr ctxt Postgres s (V.Vector a)
+  -> QGenExpr ctxt Postgres s a
+  -> QGenExpr ctxt Postgres s (V.Vector a)
+arrayAppend_ (QExpr arr) (QExpr el) =
+  QExpr (PgExpressionSyntax . mappend (emit "array_append") . pgParens . mconcat <$> sequenceA
+    [ fromPgExpression <$> arr
+    , pure (emit ", ")
+    , fromPgExpression <$> el
+    ])
+
+-- | Postgres array_prepend(value) function.
+--
+-- Prepends an element to the beginning of an array. Equivalent to the
+-- @anycompatible || anycompatiblearray@ operator.
+--
+-- Notes:
+-- - The array must be empty or one-dimensional.
+-- - If the array is NULL, the result is NULL. If the element is NULL,
+--   a NULL element is prepended.
+--
+-- @since 0.5.4.4
+arrayPrepend_
+  :: QGenExpr ctxt Postgres s a
+  -> QGenExpr ctxt Postgres s (V.Vector a)
+  -> QGenExpr ctxt Postgres s (V.Vector a)
+arrayPrepend_ (QExpr el) (QExpr arr) =
+  QExpr (PgExpressionSyntax . mappend (emit "array_prepend") . pgParens . mconcat <$> sequenceA
+    [ fromPgExpression <$> el
+    , pure (emit ", ")
+    , fromPgExpression <$> arr
+    ])
+
+-- | Postgres array_remove(value) function.
+--
+-- Removes all elements equal to the given value from the array.
+-- Comparisons use @IS NOT DISTINCT FROM@ semantics, so this can remove NULLs.
+--
+-- Notes:
+-- - The array must be one-dimensional.
+-- - Returns NULL only if the array is NULL; if the value is not present,
+--   the original array is returned unchanged.
+--
+-- @since 0.5.4.4
+arrayRemove_
+  :: QGenExpr ctxt Postgres s (V.Vector a)
+  -> QGenExpr ctxt Postgres s a
+  -> QGenExpr ctxt Postgres s (V.Vector a)
+arrayRemove_ (QExpr arr) (QExpr el) =
+  QExpr (PgExpressionSyntax . mappend (emit "array_remove") . pgParens . mconcat <$> sequenceA
+    [ fromPgExpression <$> arr
+    , pure (emit ", ")
+    , fromPgExpression <$> el
+    ])
+
+-- | Postgres array_replace(array, from, to) function.
+--
+-- Replaces each element equal to the second argument with the third.
+--
+-- Notes:
+-- - Comparisons use IS NOT DISTINCT FROM semantics; can replace NULLs.
+-- - The array must be one-dimensional.
+--
+-- Example:
+--
+-- @
+-- select_ $ pure $ arrayReplace_ (val_ $ V.fromList [1::Int32,2,5,4]) (val_ 5) (val_ 3)
+-- -- => {1,2,3,4}
+-- @
+--
+-- @since 0.5.4.4
+arrayReplace_
+  :: QGenExpr ctxt Postgres s (V.Vector a) -- ^ The array to operate on
+  -> QGenExpr ctxt Postgres s a             -- ^ The value to be replaced
+  -> QGenExpr ctxt Postgres s a             -- ^ The new value
+  -> QGenExpr ctxt Postgres s (V.Vector a)
+arrayReplace_ (QExpr arr) (QExpr fromVal) (QExpr toVal) =
+  QExpr (PgExpressionSyntax . mappend (emit "array_replace") . pgParens . mconcat <$> sequenceA
+    [ fromPgExpression <$> arr
+    , pure (emit ", ")
+    , fromPgExpression <$> fromVal
+    , pure (emit ", ")
+    , fromPgExpression <$> toVal
+    ])
+
+-- | Postgres array_shuffle(array) function.
+-- Randomly shuffles the first dimension.
+--
+-- @since 0.5.4.4
+arrayShuffle_
+  :: QGenExpr ctxt Postgres s (V.Vector a)
+  -> QGenExpr ctxt Postgres s (V.Vector a)
+arrayShuffle_ (QExpr arr) =
+  QExpr (PgExpressionSyntax . mappend (emit "array_shuffle") . pgParens . fromPgExpression <$> arr)
+
+-- | Postgres array_sample(array, n) function.
+-- Randomly selects @n@ items from the array. For multidimensional arrays,
+-- an "item" is a slice with a given first subscript.
+--
+-- Precondition: @n@ must not exceed the length of the first dimension.
+--   If n is negative, it will be treated as 0.
+--
+-- @since 0.5.4.4
+arraySample_
+  :: Integral n
+  => QGenExpr ctxt Postgres s (V.Vector a)  -- ^ The source array
+  -> QGenExpr ctxt Postgres s n             -- ^ Number of elements to sample (negative values treated as 0)
+  -> QGenExpr ctxt Postgres s (V.Vector a)
+arraySample_ (QExpr arr) (QExpr n) =
+  QExpr (PgExpressionSyntax . mappend (emit "array_sample") . pgParens . mconcat <$> sequenceA
+    [ fromPgExpression <$> arr
+    , pure (emit ", greatest(0, ")
+    , fromPgExpression <$> n
+    , pure (emit ")")
+    ])
+
+-- | Postgres array_to_string(array, delimiter) function.
+-- Converts each element to text and joins with the delimiter. NULLs are omitted.
+--
+-- @since 0.5.4.4
+arrayToString_
+  :: QGenExpr ctxt Postgres s (V.Vector a)
+  -> QGenExpr ctxt Postgres s Text
+  -> QGenExpr ctxt Postgres s Text
+arrayToString_ (QExpr arr) (QExpr delim) =
+  QExpr (PgExpressionSyntax <$> do
+    arrExpr <- fromPgExpression <$> arr
+    delimExpr <- fromPgExpression <$> delim
+    pure $ emit "array_to_string" <> pgParens (arrExpr <> emit ", " <> delimExpr))
+
+-- | Postgres array_to_string(array, delimiter, null_string) function.
+-- Converts each element to text and joins with the delimiter. NULLs are
+-- represented by the provided @null_string@.
+--
+-- @since 0.5.4.4
+arrayToStringWithNull_
+  :: QGenExpr ctxt Postgres s (V.Vector a)
+  -> QGenExpr ctxt Postgres s Text
+  -> QGenExpr ctxt Postgres s Text
+  -> QGenExpr ctxt Postgres s Text
+arrayToStringWithNull_ (QExpr arr) (QExpr delim) (QExpr nullStr) =
+  QExpr (PgExpressionSyntax <$> do
+    arrExpr <- fromPgExpression <$> arr
+    delimExpr <- fromPgExpression <$> delim
+    nullStrExpr <- fromPgExpression <$> nullStr
+    pure $ emit "array_to_string" <>
+      pgParens (mconcat [arrExpr, emit ", ", delimExpr, emit ", ", nullStrExpr]))
 -- ** Array expressions
 
 -- | An expression context that determines which types of expressions can be put
diff --git a/beam-postgres.cabal b/beam-postgres.cabal
--- a/beam-postgres.cabal
+++ b/beam-postgres.cabal
@@ -1,5 +1,5 @@
 name:                 beam-postgres
-version:              0.5.4.3
+version:              0.5.4.4
 synopsis:             Connection layer between beam and postgres
 description:          Beam driver for <https://www.postgresql.org/ PostgreSQL>, an advanced open-source RDBMS
 homepage:             https://haskell-beam.github.io/beam/user-guide/backends/beam-postgres
@@ -46,7 +46,7 @@
                       hashable             >=1.1  && <1.6,
                       lifted-base          >=0.2  && <0.3,
                       free                 >=4.12 && <5.3,
-                      time                 >=1.6  && <1.13,
+                      time                 >=1.6  && <1.15,
                       monad-control        >=1.0  && <1.1,
                       mtl                  >=2.1  && <2.4,
                       conduit              >=1.2  && <1.4,
diff --git a/test/Database/Beam/Postgres/Test/Select.hs b/test/Database/Beam/Postgres/Test/Select.hs
--- a/test/Database/Beam/Postgres/Test/Select.hs
+++ b/test/Database/Beam/Postgres/Test/Select.hs
@@ -5,6 +5,8 @@
 import           Data.Aeson
 import           Data.ByteString (ByteString)
 import           Data.Int
+import           Data.List (sort)
+import qualified Data.Text as T
 import qualified Data.Vector as V
 import           Test.Tasty
 import           Test.Tasty.HUnit
@@ -24,6 +26,16 @@
   [ testGroup "JSON"
       [ testPgArrayToJSON getConn
       ]
+  , testGroup "ARRAY functions"
+      [ testArrayReplace getConn
+      , testArrayShuffle getConn
+      , testArraySample getConn
+      , testArrayToStringBasic getConn
+      , testArrayToStringWithNull getConn
+      , testArrayAppend getConn
+      , testArrayPrepend getConn
+      , testArrayRemove getConn
+      ]
   , testGroup "UUID"
       [ testUuidFunction getConn "uuid_nil" $ \ext -> pgUuidNil ext
       , testUuidFunction getConn "uuid_ns_dns" $ \ext -> pgUuidNsDns ext
@@ -55,6 +67,73 @@
     runBeamPostgres conn $ runSelectReturningList $ select $
       return $ pgArrayToJson $ val_ $ V.fromList values
   assertEqual "JSON list" [PgJSON $ toJSON values] actual
+
+testArrayReplace :: IO ByteString -> TestTree
+testArrayReplace getConn = testFunction getConn "array_replace" $ \conn -> do
+  let arr = V.fromList [1::Int32,2,5,4]
+  res <- runBeamPostgres conn $ runSelectReturningList $ select $ do
+    pure $ arrayReplace_ (val_ arr) (val_ (5::Int32)) (val_ (3::Int32))
+  assertEqual "array_replace" [V.fromList [1,2,3,4 :: Int32]] res
+
+testArrayShuffle :: IO ByteString -> TestTree
+testArrayShuffle getConn = testFunction getConn "array_shuffle" $ \conn -> do
+  let arr = V.fromList [1::Int32,2,3,4,5]
+  res <- runBeamPostgres conn $ runSelectReturningList $ select $ do
+    pure $ arrayShuffle_ (val_ arr)
+  -- shuffled result has same length and elements, order may change
+  case res of
+    [shuf] -> do
+      assertEqual "length" (V.length arr) (V.length shuf)
+      assertBool "is permutation"
+        (sort (V.toList arr) == sort (V.toList shuf))
+    _ -> assertFailure "unexpected result"
+
+testArraySample :: IO ByteString -> TestTree
+testArraySample getConn = testFunction getConn "array_sample" $ \conn -> do
+  let arr = V.fromList [1::Int32,2,3,4,5,6]
+  res <- runBeamPostgres conn $ runSelectReturningList $ select $ do
+    pure $ arraySample_ (val_ arr) (val_ (3::Int32))
+  case res of
+    [samp] -> do
+      assertEqual "length 3" 3 (V.length samp)
+      assertBool "subset" (V.all (`V.elem` arr) samp)
+    _ -> assertFailure "unexpected result"
+
+testArrayToStringBasic :: IO ByteString -> TestTree
+testArrayToStringBasic getConn = testFunction getConn "array_to_string_basic" $ \conn -> do
+  let arr = V.fromList [1::Int32,2,3]
+  res <- runBeamPostgres conn $ runSelectReturningList $ select $ do
+    pure $ arrayToString_ (val_ arr) (val_ ",")
+  assertEqual "join" ["1,2,3" :: T.Text] res
+
+testArrayToStringWithNull :: IO ByteString -> TestTree
+testArrayToStringWithNull getConn = testFunction getConn "array_to_string_with_null" $ \conn -> do
+  let arr :: V.Vector (Maybe T.Text)
+      arr = V.fromList [Just "a", Nothing, Just "b"]
+  res <- runBeamPostgres conn $ runSelectReturningList $ select $ do
+    pure $ arrayToStringWithNull_ (val_ arr) (val_ "-") (val_ "*")
+  assertEqual "join with null" ["a-*-b" :: T.Text] res
+
+testArrayAppend :: IO ByteString -> TestTree
+testArrayAppend getConn = testFunction getConn "array_append" $ \conn -> do
+  let arr = V.fromList [1::Int32,2]
+  res <- runBeamPostgres conn $ runSelectReturningList $ select $ do
+    pure $ arrayAppend_ (val_ arr) (val_ (3::Int32))
+  assertEqual "append" [V.fromList [1,2,3 :: Int32]] res
+
+testArrayPrepend :: IO ByteString -> TestTree
+testArrayPrepend getConn = testFunction getConn "array_prepend" $ \conn -> do
+  let arr = V.fromList [2::Int32,3]
+  res <- runBeamPostgres conn $ runSelectReturningList $ select $ do
+    pure $ arrayPrepend_ (val_ (1::Int32)) (val_ arr)
+  assertEqual "prepend" [V.fromList [1,2,3 :: Int32]] res
+
+testArrayRemove :: IO ByteString -> TestTree
+testArrayRemove getConn = testFunction getConn "array_remove" $ \conn -> do
+  let arr = V.fromList [1::Int32,2,3,2]
+  res <- runBeamPostgres conn $ runSelectReturningList $ select $ do
+    pure $ arrayRemove_ (val_ arr) (val_ (2::Int32))
+  assertEqual "remove" [V.fromList [1,3 :: Int32]] res
 
 data UuidSchema f = UuidSchema
   { _uuidOssp :: f (PgExtensionEntity UuidOssp)
