2014-01-05 2 views
1

Допустим, я хочу, чтобы разобрать JSON из http://reddit.com/r/haskell.jsonСинтаксический JSON из веб-сервера в Haskell

main = do 
    rsp <- simpleHTTP (getRequest "http://www.reddit.com/r/haskell.json") 
    str <- fmap (takeWhile isAscii) (getResponseBody rsp) 

теперь у меня есть строка, готовый быть разобран. Однако decode функция эсон имеет следующий тип подписи:

decode :: FromJSON a => 
    bytestring-0.10.0.2:Data.ByteString.Lazy.Internal.ByteString -> Maybe a 

Как я могу декодировать JSON из этой строки? Или есть лучший способ декодирования из запроса GET?

ответ

4

simpleHTTP является полиморфным. Оставшийся орган реагирования может быть любым из строгих ByteString, ленивый ByteString, или String. Он выбирает один из тех, которые соответствуют значению Request ty, переданному ему. К сожалению, HTTP - это старая библиотека и плохо поддерживается - она ​​как бы минимально добавила полиморфизм, необходимый для работы с этими тремя типами, но не везде он мог бы сделать библиотеку удобной для использования. Например, использование getRequest заставляет ответ быть String, аннулируя полиморфизм в .

Вот минимальный рабочий пример захвата содержимого этого URL-адреса с помощью HTTP и декодирования их с помощью aeson.

import Network.URI 
import Network.HTTP 
import Data.Aeson 

-- There's absolutely no reason that this function shouldn't be in HTTP. 
-- It's just as unsafe and terrible as getRequest is. In fact, this is a 
-- strictly more general type than getRequest has, so there's no reason 
-- it shouldn't just replace it. 
getRequest_ :: HStream ty => String -> Request ty 
getRequest_ s = let Just u = parseURI s in defaultGETRequest_ u 

main :: IO() 
main = do 
    rsp <- simpleHTTP $ getRequest_ "http://www.reddit.com/r/haskell.json" 
    body <- getResponseBody rsp 
    print (decode $ body :: Maybe Value) 

Обратите внимание, что это использование decode, что в конце концов прижимает вниз полиморфный тип simpleHTTP там. Просто в этой версии это не противоречит тому, что getRequest говорит о типе вашего кода.

+0

Это действительно 'simpleHTTP' из пакета' HTTP'. Как я могу сказать, чтобы использовать правильную 'ByteString', чтобы я мог передать ее функции' decode'? – BinRoot

+0

@Nick Просто подайте его на функцию 'decode'. Это все, что нужно, чтобы убедиться, что это правильный тип. В этом весь смысл вывода типа. – Carl

+0

После получения 'rsp', я попробовал' sb <- getResponseBody rsp', а затем 'decode sb', но это не удалось с ошибкой типа, потому что он ожидал' Data.ByteString.Lazy.Internal.ByteString', но вместо этого получил '[ Char] ' – BinRoot

Смежные вопросы