Search
Write a publication
Pull to refresh
0
0
Send message
Ну я не то чтобы собирался кого-то переубеждать. Просто в интернете кто-то неправ не люблю когда так безапелляционно утверждают очевидную чушь.
Ну по сути тот же, что и в динамическом языке:
lookup "foo" dict
эквивалентно
obj["foo"]
. Изначальный Ваш посыл ведь был в том, что «статические языки впадают в ступор».
Как видно, никакой проблемы работать с объектами неизвестной структуры нет. Правда, что полезного можно сделать с такими объектами?!.. Наверняка, у вас есть хотя бы частичные представления о структуре (например, должны присутствовать поля «foo», «bar», опционально «baz», ну и хрен его знает что еще). Никакой проблемы описать тип:


data MyFancyData = MyFancyData
  { foo :: Int
  , bar :: Text
  , baz :: Maybe Bool
  , fields :: HashMap Text Value
  }
instance FromJSON MyFancyData where
  parseJSON = withObject "MyFancyData" $ \obj -> 
    MyFancyData <$> (obj .: "foo") <*> (obj .: "bar") <*> (obj .:? "baz") <*> pure obj
instance ToJSON MyFancyData where
  toJSON = Object . fields


У вас есть почти бесплатно сериализатор/десериализатор+валидатор, а также доступ ко всем полям исходного JSON объекта. Это элементарно обобщить до


data WithRawObject a =
  { decodedVal :: a
  , rawObject  :: HashMap Text Value
  }
instance (FromJSON a) => FromJSON (WithRawObject a) where
  parseJSON = withObject "Raw" \obj ->
    WithRawObject <$> parseJSON (Object obj) <*> pure obj   


И теперь это будет работать с любым типом, для которого определен JSON десериализатор.


data MyFancyData = MyFancyData
  { foo :: Int
  , bar :: Text
  , baz :: Maybe Bool
  } deriving (Generic, FromJSON)

main = do
  bs <- queryAPI
  case eitherDecode bs of
    Left  e -> error e -- Например, поле "foo" отсутствует. Ну или это вообще не JSON
    Right (WithRawObject (MyFancyData foo_val bar_val baz_val) fields) ->
      doSmth1 foo_val bar_val baz_val
      doSmth2 fields 


А в чем ступор?
let dict = decode @(HashMap Text Value) s
А дальше то же, что в динамике

Information

Rating
Does not participate
Registered
Activity