Skip to content

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

Comments