diff --git a/libraries/base/changelog.md b/libraries/base/changelog.md
index 6ecf30498275a45e72455d886e32d92a0ab4ba57..a6ae2389aac4c8c8a78b1856ea1dda3e6037f24d 100644
--- a/libraries/base/changelog.md
+++ b/libraries/base/changelog.md
@@ -4,6 +4,7 @@
   * Restrict `Data.List.NonEmpty.unzip` to `NonEmpty (a, b) -> (NonEmpty a, NonEmpty b)`. ([CLC proposal #86](https://github.com/haskell/core-libraries-committee/issues/86))
   * Modify the implementation of `Control.Exception.throw` to avoid call-sites being inferred as diverging via precise exception.
     ([GHC #25066](https://gitlab.haskell.org/ghc/ghc/-/issues/25066), [CLC proposal #290](https://github.com/haskell/core-libraries-committee/issues/290))
+  * `Data.List.NonEmpty.{init,last,tails1}` are now defined using only total functions (rather than partial ones). ([CLC proposal #293](https://github.com/haskell/core-libraries-committee/issues/293))
 
 ## 4.21.0.0 *TBA*
   * `GHC.Desugar` has been deprecated and should be removed in GHC 9.14. ([CLC proposal #216](https://github.com/haskell/core-libraries-committee/issues/216))
diff --git a/libraries/base/src/Data/List/NonEmpty.hs b/libraries/base/src/Data/List/NonEmpty.hs
index 6e4bf638739277e0ed99ca8833e5d7cb02001a17..50a1ecb5343414bfdf5873dfc980a80d0063fb41 100644
--- a/libraries/base/src/Data/List/NonEmpty.hs
+++ b/libraries/base/src/Data/List/NonEmpty.hs
@@ -206,11 +206,13 @@ tail (_ :| as) = as
 
 -- | Extract the last element of the stream.
 last :: NonEmpty a -> a
-last ~(a :| as) = List.last (a : as)
+last (a :| []) = a
+last (_ :| (a : as)) = last (a :| as)
 
 -- | Extract everything except the last element of the stream.
 init :: NonEmpty a -> [a]
-init ~(a :| as) = List.init (a : as)
+init (_ :| []) = []
+init (a1 :| (a2 : as)) = a1 : init (a2 :| as)
 
 -- | Construct a 'NonEmpty' list from a single element.
 --
@@ -324,7 +326,7 @@ tails = fromList . List.tails . Foldable.toList
 --
 -- @since 4.18
 tails1 :: NonEmpty a -> NonEmpty (NonEmpty a)
-tails1 = fromList . List.tails1 . Foldable.toList
+tails1 xs = xs :| List.tails1 (tail xs)
 
 -- | @'insert' x xs@ inserts @x@ into the last position in @xs@ where it
 -- is still less than or equal to the next element. In particular, if the