Я бы порекомендовал использовать новый пакет aeson вместо пакета json , так как первый работает намного лучше. Вот как можно преобразовать объект JSON в запись на Haskell, используя aeson:
{-# LANGUAGE OverloadedStrings #-}
module Example where
import Control.Applicative
import Control.Monad
import Data.Aeson
data Tweet = Tweet {
from_user :: String,
to_user_id :: String,
profile_image_url :: String,
created_at :: String,
id_str :: String,
source :: String,
to_user_id_str :: String,
from_user_id_str :: String,
from_user_id :: String,
text :: String,
metadata :: String
}
instance FromJSON Tweet where
parseJSON (Object v) =
Tweet <$> v .: "from_user"
<*> v .: "to_user_id"
<*> v .: "profile_image_url"
<*> v .: "created_at"
<*> v .: "id_str"
<*> v .: "source"
<*> v .: "to_user_id_str"
<*> v .: "from_user_id_str"
<*> v .: "from_user_id"
<*> v .: "text"
<*> v .: "metadata"
-- A non-Object value is of the wrong type, so use mzero to fail.
parseJSON _ = mzero
Затем используйте Data.Aeson.json
, чтобы получить attoparsec парсер, который преобразует ByteString
в Value
. Позвоните fromJSON
на Value
, чтобы попытаться проанализировать его в вашей записи. Обратите внимание, что в этих двух шагах участвуют два различных синтаксических анализатора: синтаксический анализатор Data.Attoparsec.Parser
для преобразования ByteString
в общий JSON Value
и затем анализатор Data.Aeson.Types.Parser
для преобразования значения JSON в запись. Обратите внимание, что оба шага могут потерпеть неудачу:
- Первый анализатор может завершиться ошибкой, если
ByteString
не является допустимым значением JSON.
- Второй синтаксический анализатор может потерпеть неудачу, если (действительное) значение JSON не содержит одно из полей, упомянутых в вашей реализации
fromJSON
.
Пакет aeson предпочитает новый тип Unicode Text
(определенный в пакете text ) более старому типу String
. Тип Text
имеет гораздо более эффективное представление памяти, чем String
, и обычно работает лучше. Я бы порекомендовал вам изменить тип Tweet
на Text
вместо String
.
Если вам когда-либо понадобится выполнить преобразование между String
и Text
, используйте функции pack
и unpack
, определенные в Data.Text
. Обратите внимание, что такие преобразования требуют времени O (n), поэтому избегайте их как можно больше (то есть всегда используйте Text
).