parsing,haskell,monads,applicative,aeson
Essentially, you need a Parser [a] -> Parser NE.NonEmpty transformer, which is relatively easy: -- toNonEmptyP :: Parser [a] -> Parser NE.NonEmtpy toNonEmptyP p = fmap NE.nonEmpty p >>= maybe mzero return We map NE.nonEmpty on our regular list parser, which gives us Parser (Maybe NE.NonEmpty). We then inspect the...
The lens package has useful functions for inspecting tree-like structures like JSON Values. There's also the lens-aeson package with extra JSON-specific functions. import Data.Text import Data.Aeson import Data.Aeson.Lens (_Value,_String) -- this is from lens-aeson import Data.Foldable (toList) import Control.Lens (Fold,folding,universeOf,toListOf,paraOf,preview) We can begin by defining a lens Fold that extracts...
haskell,monads,composition,parsec,aeson
I was pointed to a nice solution To start with, here is how we can do it. parseJSON (Object o) = User . join <$> (traverse (.:? "url") =<< (o .:? "image")) Here, we get Parser (Maybe Object) and pass it to the next monadic action, which works with Maybe...
It might be that your API endpoint is not returning UTF-8, but ISO-8859-1. Then the \163 would translate to a £ (pound) symbol, which would make sense given the context. So I'd recommend using the text-icu package to convert your incoming ByteString to Text and then feed this to Aeson....
module AesonFun(collapse) where import qualified Data.Map as M (empty, Map, insert, lookup) import qualified Data.HashMap.Strict as HM (toList) import qualified Data.List as L (foldl') import qualified Data.Aeson as Ae (decode, ) import qualified Data.Text as T (unpack, Text) import Data.Aeson.Types as AT import qualified Data.ByteString.Lazy.Char8 as BS ( pack )...
First of all use lens-aeson not aeson-lens. aeson-lens hasn't been updated in a while and I don't think all its lenses are law-abiding. Since they both share Data.Aeson.Lens you'll have to run ghc-pkg unregister aeson-lens (or cabal sandbox hc-pkg unregister aeson-lens if you're using a sandbox). You haven't described exactly...
Both lens and aeson have functions to allow customizable handling of field and constructor names. Since aeson's default is not what you want, and wouldn't work anyway if you want the lens names to be the same as the JSON field names, let's change the aeson configuration: {-# LANGUAGE DeriveGeneric...
The FromJSON definition should read: instance FromJSON Privacy where parseJSON (Object v) = createPrivacy <$> (v .: "value") Complete working example: {-# LANGUAGE OverloadedStrings #-} import Data.Text import Data.Aeson import Control.Applicative import Control.Monad data Privacy = Everyone | AllFriends | FriendsOfFriends | Self deriving (Show) instance FromJSON Privacy where parseJSON...
Haskell need help from you about the type of your expression result since in the current call it's not possible to infer it: > fromJSON $ toJSON t :: Result TemperatureType ...
The reason for the error is that decode does not always succeed. Its type is decode :: Data a => ByteString -> Maybe a Correspondingly, (decode <$>) :: Data a => IO ByteString -> IO (Maybe a) -- desired type, IO Temperatures, won't unify The type error message gives you...
deriveJSON and friends are Template Haskell functions which will generate instances for you. As such, you should not try to list them in the deriving clause. Instead, call them in a splice at the top level like this: {-# LANGUAGE TemplateHaskell #-} import Data.Aeson.TH data Person = Person { foo...
haskell,generics,type-systems,aeson
List all record fields This one is very much possible, and it's indeed done by recursing on the structure of Rep, using a class. The solution below works for single-constructor types and returns empty string names for fields without selectors: {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE...
This will compile: commandProcessor :: Handle -> IO () commandProcessor handle = do line <- BS.hGetLine handle let lazyLine = BL.fromChunks [line] let Just login = decode lazyLine :: Maybe LogIn hPutStrLn handle "." --(show login) commandProcessor handle Basically, you need to tell aeson's decode what you want to decode...
In its current form, your code can only parse a single line of the form {"date":"2015-04-12T20:36:25+00:00", "temperature":7} : it tries to parse the input into a Temperatures, but can't find a date key into the root object because it only has a temperatures key. The problem is that your Temperatures...
You can do this with or without lens. Lenses are nice because they allow you to compose the lenses you write with other lenses later. However if you don't need this it might be overkill. First realize that when you write a FromJSON instance you write a function with this...
You want to replace nth 0 with values which is a traversal over Aeson arrays. Also, since you have a traversal with multiple results and want a list rather than a Maybe, you have to use ^.. instead of ^?. *Main> locations ^.. key "Locations" . values . key "averageReview"...
The problem is your usage of pack from the Char8 module, which doesn't work with non-Latin 1 data. Instead, use encodeUtf8 from text.
I couldn't get your code to compile, but that shouldn't matter. I assume that you have a function of type fromStringTraversal :: (AsValue t, FromJSON v, ToJSON v, Default v) => String -> Traversal' t v fromStringTraversal = undefined Then to write your instance, simply inline the definition of Traversal'...
The github package defines a convenience operator to define array fields: -- | A slightly more generic version of Aeson's @(.:?)@, using `mzero' instead -- of `Nothing'. (.:<) :: (FromJSON a) => Object -> T.Text -> Parser [a] obj .:< key = case Map.lookup key obj of Nothing -> pure...
Why doesn't parseTime do exactly what you want? parseTime defaultTimeLocale "%F" is exactly the inverse (up to Just) of showGregorian, as demonstrated by the following snippet that you can paste into GHCi. import System.Locale import Data.Time.Format import Data.Time.Calendar let test = parseTime defaultTimeLocale "%F" . showGregorian :: Day -> Maybe...
The following solution makes use of the lens and lens-aeson packages: {-# LANGUAGE FlexibleInstances #-} import Control.Lens (view,pre,ix) -- from lens import Control.Lens.Reified (ReifiedTraversal(..)) import Data.Aeson -- from aeson import Data.Aeson.Lens (_Object) -- from lens-aeson import Data.Text -- form text instance Monoid (ReifiedTraversal s s s s) where mempty =...
Let's approach this problem step-by-step. First I assume for the sake of the example that names and content are just String: type DirectoryName = String type DocumentName = String type DocumentContent = String You mention that you want to serialise Document and Directory separately. Maybe you want to work with...
No, you cannot pattern match the way you are trying to do here. A JSON Array can contain values of different types, and you cannot pattern match on all values in a list like they where one. There are several ways to solve your actual problem here. There is a...