Haskell:
Working with JSON
How to:
Haskell doesn’t have built-in support for JSON like JavaScript, but with the help of third-party libraries such as Aeson, handling JSON becomes straightforward. Aeson provides both high-level and low-level functions for encoding (converting Haskell values to JSON) and decoding (parsing JSON into Haskell values).
Installing Aeson
First, add Aeson to your project’s dependencies by updating your .cabal
file or using Stack or Cabal directly:
cabal update && cabal install aeson
or, if you are using Stack:
stack install aeson
Parsing JSON
Let’s start with a basic example of decoding JSON data into a Haskell type. Suppose we have the following JSON representing a person:
{
"name": "John Doe",
"age": 30
}
First, define a corresponding Haskell data type and make it an instance of FromJSON
:
{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics (Generic)
import Data.Aeson (FromJSON, decode)
import qualified Data.ByteString.Lazy as B
data Person = Person
{ name :: String
, age :: Int
} deriving (Generic, Show)
instance FromJSON Person
-- Function to decode JSON from a file
decodePerson :: FilePath -> IO (Maybe Person)
decodePerson filePath = do
personJson <- B.readFile filePath
return $ decode personJson
Usage:
Assuming person.json
contains the JSON data shown above, run:
main :: IO ()
main = do
maybePerson <- decodePerson "person.json"
print maybePerson
Sample Output:
Just (Person {name = "John Doe", age = 30})
Encoding Haskell Values as JSON
To convert a Haskell value back to JSON, you need to make your type an instance of ToJSON
and then use encode
.
import Data.Aeson (ToJSON, encode)
import GHC.Generics (Generic)
-- Assuming the Person type from before
instance ToJSON Person
encodePerson :: Person -> B.ByteString
encodePerson = encode
main :: IO ()
main = do
let person = Person "Jane Doe" 32
putStrLn $ show $ encodePerson person
Sample Output:
{"name":"Jane Doe","age":32}
These examples demonstrate the basics of working with JSON in Haskell using Aeson. Remember, Aeson offers much more, including custom parsing rules, working with complex nested JSON, and much more, suitable for various needs and scenarios.