Экземпляр FromJSON для ключа HashMap нового типа
Я сделал новый тип UUID
в моем заявлении представлять Text
Идентификаторы.
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
...
newtype UUID =
UUID Text
deriving (Eq, Generic, FromJSON, ToJSON, FromField, ToField, FromText, Show, Read, Hashable)
Моему приложению нужен экземпляр FromJSON
за HashMap UUID a
, HashMap определяет экземпляр для HashMap Text a
, есть ли способ использовать его при определении моего?
Если бы мне пришлось переопределить экземпляр, как бы я написал это? Вот эквивалент из Data.Aeson.Types.Instances
:
instance (FromJSON v) => FromJSON (H.HashMap Text v) where
parseJSON = withObject "HashMap Text a" $ H.traverseWithKey (\k v -> parseJSON v <?> Key k)
Как бы вы написали это для UUID
? Где Key
а также <?>
определены, и как я могу легко найти это самостоятельно? Кажется, Google не помог.
1 ответ
Ваш UUID
это новый тип, так что у вас есть
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Coerce
-- other imports...
instance (FromJSON v) => FromJSON (HashMap UUID v) where
parseJSON = coerce (parseJSON :: Value -> Parser (HashMap Text v))
Или, возможно, более простой способ
parseJSON = fmap (fromList . map (\(x,y) -> (UUID x,y)) . toList) . parseJSON
Который просто анализирует Text HashMap, а затем преобразует его в индексированный по UUID. Тем не менее coerce
версия лучше, так как она не имеет затрат времени выполнения.