2013-06-03 1 views
4

Я пытаюсь десериализовать поток данных, состоит (концептуально) пары ("TypeName", "blah", где "blah" подходит для read для некоторого объекта типа TypeName.Динамически реинкарнация типа

Есть ли способ динамически выбрать тип результата read? Использую ли я что-то вроде Data.Dynamic или Data.Typable?

+3

Только если у вас есть какие-то реестр для всех типов вам нужно. – augustss

+0

Реестр? У меня есть закрытый набор типов, но я не уверен, как это использовать. Хм. Я занимаюсь созданием экземпляра 'Read' для' Data.Typable.TypeRep'. – jpaugh

+2

С закрытым набором типов вы можете использовать оператор case для имени типа, каждый рычаг с использованием read и toDyn с сигнатурой типа. – augustss

ответ

2

Это должно направить вас в правильном направлении:

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) 
+0

Спасибо. Я затрудню это, добавив много шаблонов Haskell, но я пришел к (почти) тому же выводу. – jpaugh

Смежные вопросы