{-
It would be nice to be able to derive a `FFunctor` instance for some data types as
shown below
-}

class FFunctor f where
  ffmap :: (forall a. m a -> n a) -> f m -> f n

  -- can we define a default ffmap which would work when m :: Type -> Type?
  -- default ffmap

  
-- Application  
  
data UserRepository (m :: Type -> Type) = UserRepository {
  saveUser :: User -> m (),
  findUser :: m User
} 
-- what kind of deriving clause do we need here?
-- deriving Something  

userRepositoryWithConfig :: UserRepository (ReaderT Int IO)
userRepositoryWithConfig = UserRepository { 
  saveUser = const (pure ()),
  findUser = pure User
}

userRepository :: UserRepository IO
userRepository = ffmap (runReaderT 1) userRepositoryWithConfig