whenWVarIsFreshButCacheStaled :: (Eq v, Q.Arbitrary v) =>
    (IO (v, v, WV.WVar v, WV.WCached v) -> HS.Spec) -> HS.Spec
whenWVarIsFreshButCacheStaled f =
    HS.describe "when WVar is fresh but cache staled" $ f prepare
  where
    prepare = do
        val1 <- Q.generate Q.arbitrary
        val2 <- Q.generate $ Q.arbitrary `Q.suchThat` (/= val1)
        wv   <- WV.newWVar val1
        wc   <- WV.cacheWVar wv
        WV.putWVar wv val2
        return (val1, val2, wv, wc)
whenWVarIsFreshButCacheStaled :: (Eq v, Q.Arbitrary v) =>
    (IO (v, v, WV.WVar v, WV.WCached v) -> HS.Spec) -> HS.Spec
whenWVarIsFreshButCacheStaled f =
    HS.describe "when WVar is fresh but cache staled" $ f prepare
  where
    prepare = do
        val1 <- Q.generate Q.arbitrary
        val2 <- Q.generate $ Q.arbitrary `Q.suchThat` (/= val1)
        wv   <- WV.newWVar val1
        wc   <- WV.cacheWVar wv
        WV.putWVar wv val2
        return (val1, val2, wv, wc)
whenWVarIsFreshButCacheStaled f =
    HS.describe "when WVar is fresh but cache staled" $ f prepare
  where
    prepare = do
        val1 <- Q.generate Q.arbitrary
        val2 <- Q.generate $ Q.arbitrary `Q.suchThat` (/= val1)
        wv   <- WV.newWVar val1
        wc   <- WV.cacheWVar wv
        WV.putWVar wv val2
        return (val1, val2, wv, wc)