diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,9 @@
 Changelog for Extra
 
+1.7.10, released 2021-08-29
+    #81, add assertIO function
+    #85, add !? to do !! list indexing returning a Maybe
+    #80, add strict Var functions modifyVar', modifyVar_', writeVar'
 1.7.9, released 2020-12-19
     #72, add pureIf
     #73, make takeEnd, dropEnd, splitAtEnd: return immediately if i <= 0
diff --git a/Generate.hs b/Generate.hs
--- a/Generate.hs
+++ b/Generate.hs
@@ -1,5 +1,5 @@
 -- This module generates the files src/Extra.hs and test/TestGen.hs.
--- Either call "runhaskell Generate" or start "ghci" and use ":generate".
+-- Either call "runghc Generate" or start "ghci" and use ":generate".
 
 module Generate(main) where
 
@@ -24,7 +24,7 @@
         let funcs = filter validIdentifier $ takeWhile (/= "where") $
                     words $ replace "," " " $ drop1 $ dropWhile (/= '(') $
                     unlines $ filter (\x -> not $ any (`isPrefixOf` trim x) ["--","#"]) $ lines src
-        let tests = mapMaybe (stripPrefix "-- > ") $ lines src
+        let tests = if mod `elem` excludeTests then [] else mapMaybe (stripPrefix "-- > ") $ lines src
         pure (mod, funcs, tests)
     writeFileBinaryChanged "src/Extra.hs" $ unlines $
         ["-- GENERATED CODE - DO NOT MODIFY"
@@ -49,8 +49,6 @@
         ,"{-# LANGUAGE ExtendedDefaultRules, ScopedTypeVariables, TypeApplications, ViewPatterns #-}"
         ,"module TestGen(tests) where"
         ,"import TestUtil"
-        ,"import qualified Data.List"
-        ,"import qualified Data.List.NonEmpty.Extra"
         ,"import qualified Data.Ord"
         ,"import Test.QuickCheck.Instances.Semigroup ()"
         ,"default(Maybe Bool,Int,Double,Maybe (Maybe Bool),Maybe (Maybe Char))"
@@ -71,11 +69,19 @@
         writeFileBinary file x
 
 exclude :: [String]
-exclude = ["Data.Foldable.Extra"] -- because all their imports clash
+exclude =
+    ["Data.Foldable.Extra" -- because all their imports clash
+    ]
 
+excludeTests :: [String]
+-- FIXME: Should probably generate these in another module
+excludeTests =
+    ["Data.List.NonEmpty.Extra" -- because !? clashes and is tested
+    ]
+
 hidden :: String -> [String]
 hidden "Data.List.NonEmpty.Extra" = words
-    "cons snoc sortOn union unionBy nubOrd nubOrdBy nubOrdOn"
+    "cons snoc sortOn union unionBy nubOrd nubOrdBy nubOrdOn (!?)"
 hidden _ = []
 
 notHidden :: String -> String -> Bool
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright Neil Mitchell 2014-2020.
+Copyright Neil Mitchell 2014-2021.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Extra [![Hackage version](https://img.shields.io/hackage/v/extra.svg?label=Hackage)](https://hackage.haskell.org/package/extra) [![Stackage version](https://www.stackage.org/package/extra/badge/nightly?label=Stackage)](https://www.stackage.org/package/extra) [![Build status](https://img.shields.io/github/workflow/status/ndmitchell/extra/ci.svg)](https://github.com/ndmitchell/extra/actions)
+# Extra [![Hackage version](https://img.shields.io/hackage/v/extra.svg?label=Hackage)](https://hackage.haskell.org/package/extra) [![Stackage version](https://www.stackage.org/package/extra/badge/nightly?label=Stackage)](https://www.stackage.org/package/extra) [![Build status](https://img.shields.io/github/workflow/status/ndmitchell/extra/ci/master.svg)](https://github.com/ndmitchell/extra/actions)
 
 A library of extra functions for the standard Haskell libraries. Most functions are simple additions, filling out missing functionality. A few functions are available in later versions of GHC, but this package makes them available back to GHC 7.10. A few examples:
 
@@ -24,4 +24,4 @@
 
 ## Contributing
 
-My general contribution preferences are [available here](https://github.com/ndmitchell/neil#contributions). In addition, this repo contains some generated code which is checked in, namely [src/Extra.hs](src/Extra.hs) and [test/TestGen.hs](test/TestGen.hs). You can generate those files by either running `runhaskell Generate.hs` or `ghci` (which uses the [`.ghci` file](.ghci)) and typing `:generate`. All PR's should contain regenerated versions of those files.
+My general contribution preferences are [available here](https://github.com/ndmitchell/neil#contributions). In addition, this repo contains some generated code which is checked in, namely [src/Extra.hs](src/Extra.hs) and [test/TestGen.hs](test/TestGen.hs). You can generate those files by either running `runghc Generate.hs` or `ghci` (which uses the [`.ghci` file](.ghci)) and typing `:generate`. All PR's should contain regenerated versions of those files.
diff --git a/extra.cabal b/extra.cabal
--- a/extra.cabal
+++ b/extra.cabal
@@ -1,13 +1,13 @@
-cabal-version:      >= 1.18
+cabal-version:      1.18
 build-type:         Simple
 name:               extra
-version:            1.7.9
+version:            1.7.10
 license:            BSD3
 license-file:       LICENSE
 category:           Development
 author:             Neil Mitchell <ndmitchell@gmail.com>
 maintainer:         Neil Mitchell <ndmitchell@gmail.com>
-copyright:          Neil Mitchell 2014-2020
+copyright:          Neil Mitchell 2014-2021
 synopsis:           Extra functions I use.
 description:
     A library of extra functions for the standard Haskell libraries. Most functions are simple additions, filling out missing functionality. A few functions are available in later versions of GHC, but this package makes them available back to GHC 7.2.
@@ -15,7 +15,7 @@
     The module "Extra" documents all functions provided by this library. Modules such as "Data.List.Extra" provide extra functions over "Data.List" and also reexport "Data.List". Users are recommended to replace "Data.List" imports with "Data.List.Extra" if they need the extra functionality.
 homepage:           https://github.com/ndmitchell/extra#readme
 bug-reports:        https://github.com/ndmitchell/extra/issues
-tested-with:        GHC==8.10, GHC==8.8, GHC==8.6, GHC==8.4, GHC==8.2, GHC==8.0
+tested-with:        GHC==9.0, GHC==8.10, GHC==8.8, GHC==8.6, GHC==8.4, GHC==8.2, GHC==8.0
 
 extra-doc-files:
     CHANGES.txt
diff --git a/src/Control/Concurrent/Extra.hs b/src/Control/Concurrent/Extra.hs
--- a/src/Control/Concurrent/Extra.hs
+++ b/src/Control/Concurrent/Extra.hs
@@ -18,7 +18,11 @@
     -- * Lock
     Lock, newLock, withLock, withLockTry,
     -- * Var
-    Var, newVar, readVar, writeVar, modifyVar, modifyVar_, withVar,
+    Var, newVar, readVar,
+    writeVar, writeVar',
+    modifyVar, modifyVar',
+    modifyVar_, modifyVar_',
+    withVar,
     -- * Barrier
     Barrier, newBarrier, signalBarrier, waitBarrier, waitBarrierMaybe,
     ) where
@@ -30,6 +34,7 @@
 import Data.Either.Extra
 import Data.Functor
 import Prelude
+import Data.Tuple.Extra (dupe)
 
 
 -- | On GHC 7.6 and above with the @-threaded@ flag, brackets a call to 'setNumCapabilities'.
@@ -152,13 +157,33 @@
 writeVar :: Var a -> a -> IO ()
 writeVar v x = modifyVar_ v $ const $ pure x
 
+-- | Strict variant of 'writeVar'
+writeVar' :: Var a -> a -> IO ()
+writeVar' v x = modifyVar_' v $ const $ pure x
+
 -- | Modify a 'Var' producing a new value and a return result.
 modifyVar :: Var a -> (a -> IO (a, b)) -> IO b
 modifyVar (Var x) f = modifyMVar x f
 
+-- | Strict variant of 'modifyVar''
+modifyVar' :: Var a -> (a -> IO (a, b)) -> IO b
+modifyVar' x f = do
+    (newContents, res) <- modifyVar x $ \v -> do
+        (newContents, res) <- f v
+        pure (newContents, (newContents, res))
+    evaluate newContents
+    pure res
+
 -- | Modify a 'Var', a restricted version of 'modifyVar'.
 modifyVar_ :: Var a -> (a -> IO a) -> IO ()
 modifyVar_ (Var x) f = modifyMVar_ x f
+
+-- | Strict variant of 'modifyVar_'
+modifyVar_' :: Var a -> (a -> IO a) -> IO ()
+modifyVar_' x f = do
+    newContents <- modifyVar x (fmap dupe . f)
+    _ <- evaluate newContents
+    pure ()
 
 -- | Perform some operation using the value in the 'Var',
 --   a restricted version of 'modifyVar'.
diff --git a/src/Control/Exception/Extra.hs b/src/Control/Exception/Extra.hs
--- a/src/Control/Exception/Extra.hs
+++ b/src/Control/Exception/Extra.hs
@@ -13,7 +13,7 @@
     retry, retryBool,
     errorWithoutStackTrace,
     showException, stringException,
-    errorIO,
+    errorIO, assertIO,
     -- * Exception catching/ignoring
     ignore,
     catch_, handle_, try_,
@@ -85,6 +85,13 @@
 withFrozenCallStack = id
 #endif
 
+-- | An 'IO' action that when evaluated calls 'assert' in the 'IO' monad, which throws an 'AssertionFailed' exception if the argument is 'False'.
+--   With optimizations enabled (and @-fgnore-asserts@) this function ignores its argument and does nothing.
+--
+-- > catch (assertIO True  >> pure 1) (\(x :: AssertionFailed) -> pure 2) == pure 1
+-- > seq (assertIO False) (print 1) == print 1
+assertIO :: Partial => Bool -> IO ()
+assertIO x = withFrozenCallStack $ evaluate $ assert x ()
 
 -- | Retry an operation at most /n/ times (/n/ must be positive).
 --   If the operation fails the /n/th time it will throw that final exception.
diff --git a/src/Data/List/Extra.hs b/src/Data/List/Extra.hs
--- a/src/Data/List/Extra.hs
+++ b/src/Data/List/Extra.hs
@@ -18,7 +18,7 @@
     wordsBy, linesBy,
     breakOn, breakOnEnd, splitOn, split, chunksOf,
     -- * Basics
-    headDef, lastDef, notNull, list, unsnoc, cons, snoc,
+    headDef, lastDef, (!?), notNull, list, unsnoc, cons, snoc,
     drop1, dropEnd1, mconcatMap, compareLength, comparingLength,
     -- * Enum operations
     enumerate,
@@ -141,6 +141,19 @@
 lastDef d xs = foldl (\_ x -> x) d xs -- I know this looks weird, but apparently this is the fastest way to do this: https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.List.html#last
 {-# INLINE lastDef #-}
 
+-- | A total variant of the list index function `(!!)`.
+--
+-- > [2,3,4] !? 1    == Just 3
+-- > [2,3,4] !? (-1) == Nothing
+-- > []      !? 0    == Nothing
+(!?) :: [a] -> Int -> Maybe a
+xs !? n
+  | n < 0     = Nothing
+             -- Definition adapted from GHC.List
+  | otherwise = foldr (\x r k -> case k of
+                                   0 -> Just x
+                                   _ -> r (k-1)) (const Nothing) xs n
+{-# INLINABLE (!?) #-}
 
 -- | A composition of 'not' and 'null'.
 --
@@ -237,7 +250,7 @@
 
 
 -- | 'zip' against an enumeration.
---   Never truncates the output - raises an error if the enumeration runs out.
+--   Truncates the output if the enumeration runs out.
 --
 -- > \i xs -> zip [i..] xs == zipFrom i xs
 -- > zipFrom False [1..3] == [(False,1),(True, 2)]
@@ -245,7 +258,7 @@
 zipFrom = zipWithFrom (,)
 
 -- | 'zipFrom' generalised to any combining operation.
---   Never truncates the output - raises an error if the enumeration runs out.
+--   Truncates the output if the enumeration runs out.
 --
 -- > \i xs -> zipWithFrom (,) i xs == zipFrom i xs
 zipWithFrom :: Enum a => (a -> b -> c) -> a -> [b] -> [c]
diff --git a/src/Data/List/NonEmpty/Extra.hs b/src/Data/List/NonEmpty/Extra.hs
--- a/src/Data/List/NonEmpty/Extra.hs
+++ b/src/Data/List/NonEmpty/Extra.hs
@@ -4,7 +4,7 @@
 --   also exports the existing "Data.List.NonEmpty" functions.
 module Data.List.NonEmpty.Extra(
     module Data.List.NonEmpty,
-    (|:), (|>), snoc,
+    (|:), (|>), snoc, (!?),
     appendl, appendr,
     sortOn, union, unionBy,
     nubOrd, nubOrdBy, nubOrdOn,
@@ -36,6 +36,18 @@
 -- > [1,2,3] |: 4 |> 5 == 1 :| [2,3,4,5]
 (|:) :: [a] -> a -> NonEmpty a
 (|:) xs x = foldr cons (pure x) xs
+
+-- | A total variant of the list index function `(!?)`.
+--
+-- > (2 :| [3,4]) !? 1    == Just 3
+-- > (2 :| [3,4]) !? (-1) == Nothing
+-- > (1 :| [])    !? 1    == Nothing
+(!?) :: NonEmpty a -> Int -> Maybe a
+(!?) ~(x :| xs) n
+  | n == 0 = Just x
+  | n > 0  = xs List.!? (n - 1)
+  | otherwise = Nothing
+infixl 9 !?
 
 -- | Append a list to a non-empty list.
 --
diff --git a/src/Extra.hs b/src/Extra.hs
--- a/src/Extra.hs
+++ b/src/Extra.hs
@@ -8,10 +8,10 @@
 module Extra {-# DEPRECATED "This module is provided as documentation of all new functions, you should import the more specific modules directly." #-} (
     -- * Control.Concurrent.Extra
     -- | Extra functions available in @"Control.Concurrent.Extra"@.
-    withNumCapabilities, once, onceFork, Lock, newLock, withLock, withLockTry, Var, newVar, readVar, writeVar, modifyVar, modifyVar_, withVar, Barrier, newBarrier, signalBarrier, waitBarrier, waitBarrierMaybe,
+    withNumCapabilities, once, onceFork, Lock, newLock, withLock, withLockTry, Var, newVar, readVar, writeVar, writeVar', modifyVar, modifyVar', modifyVar_, modifyVar_', withVar, Barrier, newBarrier, signalBarrier, waitBarrier, waitBarrierMaybe,
     -- * Control.Exception.Extra
     -- | Extra functions available in @"Control.Exception.Extra"@.
-    Partial, retry, retryBool, errorWithoutStackTrace, showException, stringException, errorIO, ignore, catch_, handle_, try_, catchJust_, handleJust_, tryJust_, catchBool, handleBool, tryBool,
+    Partial, retry, retryBool, errorWithoutStackTrace, showException, stringException, errorIO, assertIO, ignore, catch_, handle_, try_, catchJust_, handleJust_, tryJust_, catchBool, handleBool, tryBool,
     -- * Control.Monad.Extra
     -- | Extra functions available in @"Control.Monad.Extra"@.
     whenJust, whenJustM, pureIf, whenMaybe, whenMaybeM, unit, maybeM, fromMaybeM, eitherM, loop, loopM, whileM, whileJustM, untilJustM, partitionM, concatMapM, concatForM, mconcatMapM, mapMaybeM, findM, firstJustM, fold1M, fold1M_, whenM, unlessM, ifM, notM, (||^), (&&^), orM, andM, anyM, allM,
@@ -23,7 +23,7 @@
     writeIORef', atomicWriteIORef', atomicModifyIORef_, atomicModifyIORef'_,
     -- * Data.List.Extra
     -- | Extra functions available in @"Data.List.Extra"@.
-    lower, upper, trim, trimStart, trimEnd, word1, line1, escapeHTML, escapeJSON, unescapeHTML, unescapeJSON, dropEnd, takeEnd, splitAtEnd, breakEnd, spanEnd, dropWhileEnd', takeWhileEnd, stripSuffix, stripInfix, stripInfixEnd, dropPrefix, dropSuffix, wordsBy, linesBy, breakOn, breakOnEnd, splitOn, split, chunksOf, headDef, lastDef, notNull, list, unsnoc, cons, snoc, drop1, dropEnd1, mconcatMap, compareLength, comparingLength, enumerate, groupSort, groupSortOn, groupSortBy, nubOrd, nubOrdBy, nubOrdOn, nubOn, groupOn, nubSort, nubSortBy, nubSortOn, maximumOn, minimumOn, sum', product', sumOn', productOn', disjoint, disjointOrd, disjointOrdBy, allSame, anySame, repeatedly, firstJust, concatUnzip, concatUnzip3, zipFrom, zipWithFrom, zipWithLongest, replace, merge, mergeBy,
+    lower, upper, trim, trimStart, trimEnd, word1, line1, escapeHTML, escapeJSON, unescapeHTML, unescapeJSON, dropEnd, takeEnd, splitAtEnd, breakEnd, spanEnd, dropWhileEnd', takeWhileEnd, stripSuffix, stripInfix, stripInfixEnd, dropPrefix, dropSuffix, wordsBy, linesBy, breakOn, breakOnEnd, splitOn, split, chunksOf, headDef, lastDef, (!?), notNull, list, unsnoc, cons, snoc, drop1, dropEnd1, mconcatMap, compareLength, comparingLength, enumerate, groupSort, groupSortOn, groupSortBy, nubOrd, nubOrdBy, nubOrdOn, nubOn, groupOn, nubSort, nubSortBy, nubSortOn, maximumOn, minimumOn, sum', product', sumOn', productOn', disjoint, disjointOrd, disjointOrdBy, allSame, anySame, repeatedly, firstJust, concatUnzip, concatUnzip3, zipFrom, zipWithFrom, zipWithLongest, replace, merge, mergeBy,
     -- * Data.List.NonEmpty.Extra
     -- | Extra functions available in @"Data.List.NonEmpty.Extra"@.
     (|:), (|>), appendl, appendr, maximum1, minimum1, maximumBy1, minimumBy1, maximumOn1, minimumOn1,
@@ -59,7 +59,7 @@
 import Data.Either.Extra
 import Data.IORef.Extra
 import Data.List.Extra
-import Data.List.NonEmpty.Extra hiding (cons, snoc, sortOn, union, unionBy, nubOrd, nubOrdBy, nubOrdOn)
+import Data.List.NonEmpty.Extra hiding (cons, snoc, sortOn, union, unionBy, nubOrd, nubOrdBy, nubOrdOn, (!?))
 import Data.Tuple.Extra
 import Data.Version.Extra
 import Numeric.Extra
diff --git a/test/TestGen.hs b/test/TestGen.hs
--- a/test/TestGen.hs
+++ b/test/TestGen.hs
@@ -4,8 +4,6 @@
 {-# LANGUAGE ExtendedDefaultRules, ScopedTypeVariables, TypeApplications, ViewPatterns #-}
 module TestGen(tests) where
 import TestUtil
-import qualified Data.List
-import qualified Data.List.NonEmpty.Extra
 import qualified Data.Ord
 import Test.QuickCheck.Instances.Semigroup ()
 default(Maybe Bool,Int,Double,Maybe (Maybe Bool),Maybe (Maybe Char))
@@ -26,6 +24,8 @@
     testGen "ignore (fail \"die\") == pure ()" $ ignore (fail "die") == pure ()
     testGen "catch (errorIO \"Hello\") (\\(ErrorCall x) -> pure x) == pure \"Hello\"" $ catch (errorIO "Hello") (\(ErrorCall x) -> pure x) == pure "Hello"
     testGen "seq (errorIO \"foo\") (print 1) == print 1" $ seq (errorIO "foo") (print 1) == print 1
+    testGen "catch (assertIO True  >> pure 1) (\\(x :: AssertionFailed) -> pure 2) == pure 1" $ catch (assertIO True  >> pure 1) (\(x :: AssertionFailed) -> pure 2) == pure 1
+    testGen "seq (assertIO False) (print 1) == print 1" $ seq (assertIO False) (print 1) == print 1
     testGen "retry 1 (print \"x\")  == print \"x\"" $ retry 1 (print "x")  == print "x"
     testGen "retry 3 (fail \"die\") == fail \"die\"" $ retry 3 (fail "die") == fail "die"
     testGen "whenJust Nothing  print == pure ()" $ whenJust Nothing  print == pure ()
@@ -107,6 +107,9 @@
     testGen "lastDef 1 []      == 1" $ lastDef 1 []      == 1
     testGen "lastDef 1 [2,3,4] == 4" $ lastDef 1 [2,3,4] == 4
     testGen "\\x xs -> lastDef x xs == last (x:xs)" $ \x xs -> lastDef x xs == last (x:xs)
+    testGen "[2,3,4] !? 1    == Just 3" $ [2,3,4] !? 1    == Just 3
+    testGen "[2,3,4] !? (-1) == Nothing" $ [2,3,4] !? (-1) == Nothing
+    testGen "[]      !? 0    == Nothing" $ []      !? 0    == Nothing
     testGen "notNull []  == False" $ notNull []  == False
     testGen "notNull [1] == True" $ notNull [1] == True
     testGen "\\xs -> notNull xs == not (null xs)" $ \xs -> notNull xs == not (null xs)
@@ -266,15 +269,6 @@
     testGen "\\(xs :: [Int]) (ys :: [Int]) -> comparingLength xs ys == Data.Ord.comparing length xs ys" $ \(xs :: [Int]) (ys :: [Int]) -> comparingLength xs ys == Data.Ord.comparing length xs ys
     testGen "comparingLength [1,2] (1:2:3:undefined) == LT" $ comparingLength [1,2] (1:2:3:undefined) == LT
     testGen "comparingLength (1:2:3:undefined) [1,2] == GT" $ comparingLength (1:2:3:undefined) [1,2] == GT
-    testGen "(1 :| [2,3]) |> 4 |> 5 == 1 :| [2,3,4,5]" $ (1 :| [2,3]) |> 4 |> 5 == 1 :| [2,3,4,5]
-    testGen "[1,2,3] |: 4 |> 5 == 1 :| [2,3,4,5]" $ [1,2,3] |: 4 |> 5 == 1 :| [2,3,4,5]
-    testGen "appendl (1 :| [2,3]) [4,5] == 1 :| [2,3,4,5]" $ appendl (1 :| [2,3]) [4,5] == 1 :| [2,3,4,5]
-    testGen "appendr [1,2,3] (4 :| [5]) == 1 :| [2,3,4,5]" $ appendr [1,2,3] (4 :| [5]) == 1 :| [2,3,4,5]
-    testGen "(1 :| [3, 5, 3]) `union` (4 :| [5, 3, 5, 2]) == 1 :| [3, 5, 3, 4, 2]" $ (1 :| [3, 5, 3]) `union` (4 :| [5, 3, 5, 2]) == 1 :| [3, 5, 3, 4, 2]
-    testGen "Data.List.NonEmpty.Extra.nubOrd (1 :| [2, 3, 3, 4, 1, 2]) == 1 :| [2, 3, 4]" $ Data.List.NonEmpty.Extra.nubOrd (1 :| [2, 3, 3, 4, 1, 2]) == 1 :| [2, 3, 4]
-    testGen "\\xs -> Data.List.NonEmpty.Extra.nubOrd xs == Data.List.NonEmpty.Extra.nub xs" $ \xs -> Data.List.NonEmpty.Extra.nubOrd xs == Data.List.NonEmpty.Extra.nub xs
-    testGen "Data.List.NonEmpty.Extra.nubOrdBy (compare `on` Data.List.length) (\"a\" :| [\"test\",\"of\",\"this\"]) == \"a\" :| [\"test\",\"of\"]" $ Data.List.NonEmpty.Extra.nubOrdBy (compare `on` Data.List.length) ("a" :| ["test","of","this"]) == "a" :| ["test","of"]
-    testGen "Data.List.NonEmpty.Extra.nubOrdOn Data.List.length (\"a\" :| [\"test\",\"of\",\"this\"]) == \"a\" :| [\"test\",\"of\"]" $ Data.List.NonEmpty.Extra.nubOrdOn Data.List.length ("a" :| ["test","of","this"]) == "a" :| ["test","of"]
     testGen "first succ (1,\"test\") == (2,\"test\")" $ first succ (1,"test") == (2,"test")
     testGen "second reverse (1,\"test\") == (1,\"tset\")" $ second reverse (1,"test") == (1,"tset")
     testGen "firstM (\\x -> [x-1, x+1]) (1,\"test\") == [(0,\"test\"),(2,\"test\")]" $ firstM (\x -> [x-1, x+1]) (1,"test") == [(0,"test"),(2,"test")]
