2015-01-26 5 views
4

Я сражался с простым ADT, пытаясь заставить его отправиться туда и обратно в JSON, но мне не повезло, как бы я ни старался массировать или модифицировать тип , Что мне не хватает?Haskell ADTs с aeson

Когда он собирает, я всегда получаю ту же ошибку во время выполнения:

> let t = Fahrenheit 
> fromJSON $ toJSON t 
Error "when expecting a(), encountered Object instead" 

Попытка это просто дает мне «Nothing», предположительно, из-за той же ошибки: расшифровывает $ закодировать т

Я пытался следовать этим источникам, но я не могу показаться, чтобы обойти эту ошибку во время выполнения, независимо от того, что я пытаюсь: Haskell :: Aeson :: parse ADT based on field value https://www.fpcomplete.com/user/Geraldus/algebraic-data-types-adts-with-aeson

Вот одна из форм коды я использую. Сначала я попытался использовать это как тип, встроенный в другой тип, но когда это не сработало, я добавил ключ «значение», чтобы попытаться сделать синтаксический анализ этого проще (без везения).

data TemperatureType = Celsius 
        | Fahrenheit 
        deriving (Show,Read,Typeable,Data,Eq) 

-- This doesn't work either 
-- $(deriveJSON defaultOptions ''TemperatureType) 

instance ToJSON TemperatureType where 
    toJSON Fahrenheit = object [ "value" .= String "Fahrenheit" ] 
    toJSON Celsius = object [ "value" .= String "Celsius" ] 

instance FromJSON TemperatureType where 
    parseJSON (Object x) = toTemperatureType <$> x .: "value" 

toTemperatureType :: Text -> TemperatureType 
toTemperatureType "Fahrenheit" = Fahrenheit 
toTemperatureType "Celsius" = Celsius 
+1

(супер новичок здесь), что если вы поможете Haskell и сказать, что тип экстоина есть? 'fromJSON $ toJSON t :: TemperatureType' – zerkms

+1

Нет никакого свидетеля того, какой тип вы ожидаете от« fromJSON », вам нужно назначить тип в качестве рекомендуемого @zerkms. Рассмотрим случай: «Читать a => String -> Maybe a», и становится более очевидным, почему это будет так. – bitemyapp

+0

Нет, это отличная идея. Оказывается, '(fromJSON $ toJSON t) :: Result TemperatureType' работает, как и' (decode $ encode t) :: Возможно, TemperatureType'. Тем не менее, похоже, все еще не работает как встроенное значение в другом типе. Должно быть больше «ручных» типов, которые я могу указать. Странно, что это компилируется без двусмысленности. – stormont

ответ

8

Haskell нужна помощь от вас о типе вашего результата выражения, так как в настоящее время называют это не представляется возможным сделать вывод о его:

> fromJSON $ toJSON t :: Result TemperatureType 
+0

У меня была аналогичная проблема, и ты понятия не имел, какие фрустрации вы меня пощадили. Спасибо! – gnclmorais