JSON
Data.Aeson
, from the aeson
package, is a library for encoding/decoding Haskell values to/from JSON.
One of the main appeals of the library is that a JSON string, which is untyped, can be automatically parsed into a typed Haskell value.
Encoding to JSON¶
repl example
> encode [4, 3]
"[4,3]"
> encode [(4, 3)]
"[[4,3]]"
> encode ['a', 'b']
"\"ab\""
> encode 4
"4"
> encode (M.fromList [("John", 12), ("Jane", 13)])
"{\"Jane\":13,\"John\":12}"
-- an example with a custom datatype
> :set -XDeriveGeneric -XDeriveAnyClass
> data Piece = Bishop | Knight deriving (Generic, ToJSON)
> encode [Bishop, Knight]
"[\"Bishop\",\"Knight\"]"
Decoding from JSON¶
repl example
:set -XOverloadedStrings
import Data.Aeson
> eitherDecode "[1,2,3]" :: Either String [Int]
Right [1,2,3]
> eitherDecode "[1,2," :: Either String [Int]
Left "Error in $: not enough input. Expecting json list value"
> eitherDecode "[1,2,3]" :: Either String (Int, Int, Int)
Right (1,2,3)
> eitherDecode "[1,2,3]" :: Either String (Int, Int, Double)
Right (1,2,3.0)
> str = "{ \"name\": \"Joe\", \"age\": \"12\" }"
> eitherDecode str :: Either String (Map String String)
Right (fromList [("age","12"),("name","Joe")])
> eitherDecode str :: Either String Value
Right (Object (fromList [("age",String "12"),("name",String "Joe")]))
The user can determine the Haskell type that the JSON should be decoded into. Types which are possible must implement the FromJSON
typeclass, which is automatically implemented for many types, and can be derived automatically for custom types:
repl example
> :set -XDeriveGeneric -XDeriveAnyClass -XOverloadedStrings
> import GHC.Generics
> str = "{ \"name\": \"Joe\", \"age\": 12 }"
> data Person = Person { name :: Text, age :: Int}
deriving (Generic, Show, FromJSON)
> eitherDecode str :: Either String Person
Right (Person {name = "Joe", age = 12})
With lenses¶
Lenses are an extremely useful tool for working with JSON in Haskell. See here
Last update:
January 25, 2023
Created: January 12, 2023
Created: January 12, 2023