
Overall context: I'm trying to port the DelayedJob library from Ruby/Rails world to Haskell. The basic idea is to serialise a job and write it to the DB, deserialise it, and run the job using a job-runner function, which is determined by the job-type. I'm using a type-class to define the custom job-runner, something on the lines of: class (FromJSON j, ToJSON j) => DelayedJob j where runJob :: j -> AppM () data SyncContactsJob = SyncContactsJob { userId :: UserId } deriving (Eq, Show, Generic, FromJSON, ToJSON) instance DelayedJob SyncContactsJob where runJob job = do -- entire job execution logic comes here Is there **any** type-system hackery, that will let me take a runtime value, eg. "SyncContactsJob", "DoBackupJob", and use that to run the correct version of the `runJob` function? That is, how do I write the following function: invokeJob :: JobId -> AppM () invokeJob jid = do jobRow <- fetchJob jid let jtype = jobRow ^. jobtype -- this will have "SyncContactsJob" jvalue = jobRow ^. jobdata -- this will have a Data.Aeson.Value runJob (......) -- QUESTION: What do I write here to make this compile?