Data.Array is lazy, so you can just write the memoized version directly:
cache :: KnownNat n => V n x -> V n x
cache @n (V f) =
let
n = fromIntegral (natVal (Proxy @n)) :: Int
arr = array (0,n-1) [ (i, f i) | i <- [0..n-1] ]
in V (arr !)