Como atribuir um valor da monad IO a um construtor qualificado RankNType

(ATUALIZADA)

Eu fiz uma interface usando umMônada grátis para um armazenamento de dados genérico. Quero colocar o intérprete específico (:: DataStore a -> IO a) escolhido pelo usuário em tempo de execução em uma mônada de estado, juntamente com outras informações. Parece que não consigo colocar nada nesse campo na estrutura de dados.

Como coloco um valor em um campo definido como um tipo de classificação mais alta?

Abaixo está um exemplo mínimo:

{-# LANGUAGE RankNTypes, DeriveFunctor #-}

data ProgramState = PS { -- line 3
    [...]
  , storageInterface :: (forall a. DataStore a -> IO a)
  }

data DataStoreF next = 
     Create    Asset                           ( String -> next)
  |  Read      String                          ( Asset  -> next)
  |  Update    Asset                           ( Bool   -> next)
  |  UpdateAll [Asset]                         ( Bool   -> next)
  |  [...]
  deriving Functor

type DataStore = Free DataStoreF

runMemory :: (IORef (Map String Asset)) -> DataStore a -> IO a
runMemory ms (Pure a) = return a
runMemory ms (Free Create asset next) = [...]
runMemory ms (Free Read   str   next) = [...]
[...]

pickStorageInterface :: IO (DataStore a -> IO a)
pickStorageInterface = do
  opts <- parseOptions
  case (storage opts) of
     MemoryStorage -> 
       ms <- readAssetsFromDisk 
       return $ runMemory ms
     SomeOtherStorage -> [...]

restOfProgram :: StateT ProgramState IO
restOfProgram = [...]

main = do
  si <- pickStorageInterface
  let programState = PS { storageInterface = si} -- line 21
  evalState restOfProgram programState

Quando tento fazer isso, o GHC reclama que:

Main.hs: << Line 21 >>
Couldn't match type `a0' with `a'
  because type variable `a' would escape its scope
This (rigid, skolem) type variable is bound by
  a type expected by the context: DataStore a -> IO a
  at Main.hs <<line 3>>
Expected type: DataStore a -> IO a
  Actual type: DataStore a0 -> IO a0
In the `storageInterface' field of a record
  [...]

ATUALIZAR

Meu exemplo mínimo original foi o mínimo. Algumas experiências adicionais mostram que o problema surge quando preciso carregar a interface em uma mônada IO para que eu possa ler as opções da linha de comando. Atualizei o exemplo para incluir esse problema. Sabendo disso, talvez seja possível codificá-lo.

GHCI interessante me diz que os resultados de uma função do tipoIO (DataStore a -> IO a) éDataStore GHC.Prim.Any -> IO GHC.Prim.Any o que não é o que eu esperava.

questionAnswers(1)

yourAnswerToTheQuestion