我在我的应用程序中创建了一个新类型UUID
来表示Text
个ID。
{-# 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
和<?>
在哪里定义,我怎样才能自己轻松查看?霍格尔似乎没有帮助。
答案 0 :(得分:2)
您的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
版本更好,因为它没有运行时成本。