    cachedIdem f i a = do
      s <- get
      case Set.member a s of
        True -> return i
        False -> do
          b <- f a
          s' <- get
          put (Set.insert a s')
          return b
