jpaugh
jpaugh

Reputation: 7035

Dynamically reincarnating a Type

I'm trying to deserialize a stream of data, consists (conceptually) of the pair ("TypeName", "blah", where "blah" is appropriate input to read for some object of type TypeName.

Is there a way to dynamically choose read's result type? Would I use something like Data.Dynamic or Data.Typable?

Upvotes: 4

Views: 151

Answers (1)

sclv
sclv

Reputation: 38891

This should point you in the right direction:

import Data.Typeable
import Data.Dynamic
import Control.Applicative

readMay :: Read a => String -> Maybe a
readMay s = case reads s of
    (a,[]):_ -> Just a
    _ -> Nothing

reconstruct :: Typeable a => (Maybe a -> r) -> (String, String) -> r
reconstruct k (typ,val) =
    case typ of
      "string" -> k $ cast =<< (readMay val :: Maybe String)
      "int"    -> k $ cast =<< (readMay val :: Maybe Int)
      "double" -> k $ cast =<< (readMay val :: Maybe Double)

reconstructToDyn (typ,val) =
    case typ of
      "string" -> toDyn <$> (readMay val :: Maybe String)
      "int"    -> toDyn <$> (readMay val :: Maybe Int)
      "double" -> toDyn <$> (readMay val :: Maybe Double)

Upvotes: 2

Related Questions