Próbuję napisać funkcję Aeson dla FromJSON
.Parse Array w zagnieżdżonym JSONie z Aesonem
JSON:
{
"total": 1,
"movies": [
{
"id": "771315522",
"title": "Harry Potter and the Philosophers Stone (Wizard's Collection)",
"posters": {
"thumbnail": "http://content7.flixster.com/movie/11/16/66/11166609_mob.jpg",
"profile": "http://content7.flixster.com/movie/11/16/66/11166609_pro.jpg",
"detailed": "http://content7.flixster.com/movie/11/16/66/11166609_det.jpg",
"original": "http://content7.flixster.com/movie/11/16/66/11166609_ori.jpg"
}
}
]
}
ADT: data Movie = Movie {id::String, title::String}
Moja próba:
instance FromJSON Movie where
parseJSON (Object o) = do
movies <- parseJSON =<< (o .: "movies") :: Parser Array
v <- head $ decode movies
return $ Movie <$>
(v .: "movies" >>= (.: "id")) <*>
(v .: "movies" >>= (.: "title"))
parseJSON _ = mzero
Daje Couldn't match expected type 'Parser t0' with actual type 'Maybe a0' In the first argument of 'head'
.
Jak widać, próbuję wybrać pierwszy z filmów w Array
, ale nie miałbym nic przeciwko otrzymaniu listy filmów (w przypadku, gdy jest ich kilka w Tablicy).
dziękuję! Nie myślałem o wprowadzeniu innego typu. Czy mogę prosić o szybką kontynuację? Jeśli chciałbym rozszerzyć typ 'Film' o kilka dodatkowych pól, takich jak' filePath' lub 'myRating', czy poleciłbyś dodanie nowego typu' myMovie' lub wprowadzenie kilku pól 'Maybe' do' filmu' wpisz i wypełnij je po "dekodowaniu"? (Przypuszczam, że zapełnienie będzie oznaczało utworzenie nowej instancji ze wszystkimi polami, ponieważ ADT są niezmienne ..) – mb21
@ mb21: Obie metody będą działać poprawnie. To zależy od reszty twojej aplikacji. Jeśli te pola są zawsze dodawane natychmiast po dekodowaniu, może być sens tworzenia nowego typu, aby pozostałe funkcje nie musiały zajmować się "Może", które powinno zawsze być "Po prostu". Z drugiej strony, jeśli te pola są opcjonalne, warto je zachować w "Być może". – hammar
@hammar: ok, wielkie dzięki! – mb21