I do not believe that you can safely do what you are trying to do. Let me suggest an alternative approach.
Perhaps phantom types can help you here. Suppose you provide some kind of cron job service where the user performs an action every x microseconds, and the user can request at any time to see the result of the last run of this action.
Suppose you have access to the following primitives:
freshKey :: IO Key save :: Key -> Dynamic -> IO () load :: Key -> IO (Maybe Dynamic)
You must plan tasks and plan to save the results, while you still “know” in the type system what type of action.
Now, if I am a user of your API, I can use it with my own data types, which you know nothing about, if they are Typeable:
refreshFoo :: IO Foo main = do fooKey <- schedule 1000000 refreshFoo
So what have we achieved?
- Your library takes an IO user action and executes it at arbitrary points in time
- Your library saves your user data through Dynamic blobs
- Your library loads your user data through dynamic drops
All this if your library does not know anything about your user data types.
It seems to me that if you put something that you know is an I / O action in a dynamic blob, you have lost information in the type system about this thing in context, when instead you should use the specified type information, TypeRep can get the information about type at the level of values, but (as far as I know) cannot bring this information to the level of type.
source share