Объект Haskell Aeson JSON внутри массива JSON

Я пытаюсь преобразовать строку JSON в ADT

Это мой АТД:

data UserList = UserList
  { userListUsers :: [UserId] }

Это мой экземпляр FromJSON для UserList:

instance FromJSON UserList where
  parseJSON (Object o) = UserList
    <$> ((o .: "relationships") >>= (.: "users") >>= (mapM (.: "id")))

И, наконец, это моя строка JSON:

{
  "relationships": { 
    "users": [
      { "type": "User","id": "8" }
    ]
  }
}

Мой сервер Yesod выдает 400 Bad Request без какой-либо дополнительной помощи, я думаю, что, возможно, неправильно конвертирую массив users


person FtheBuilder    schedule 19.06.2016    source источник


Ответы (2)


Обновить

Ваш парсер в порядке, так как вы можете протестировать его с помощью приведенного ниже кода. Ваша реализация такая же, как и та, которую я написал с помощью do-notation.

Исходный ответ

Это должно работать:

{-# LANGUAGE OverloadedStrings #-}

import Data.Aeson
import Data.Stringable
import Control.Monad

type UserId = String

data UserList = UserList
  { userListUsers :: [UserId] }
  deriving (Show)

instance FromJSON UserList where
  parseJSON (Object o) = 
    do  r <- o .: "relationships"
        u <- r .: "users"
        idents <- forM u $ \x -> x .: "id"
        return $ UserList idents

test = do
  contents <- readFile "in"
  let e = eitherDecode (toLazyByteString contents) :: Either String UserList
  print e
person ErikR    schedule 19.06.2016
comment
Спасибо, изменение моего кода на do-notation помогло мне понять, чего мне не хватало (fromPathPiece). - person FtheBuilder; 19.06.2016

Я забыл использовать fromPathPiece, я изменил на do-нотацию, чтобы сделать ее красивее:

instance FromJSON UserList where
  parseJSON (Object o) = do  
    r <- o .: "relationships"
    u <- r .: "users"
    ids <- forM u $ \x -> do
      id <- x .: "id"
      return $ fromJust . fromPathPiece $ id
    return $ UserList ids
person FtheBuilder    schedule 19.06.2016