1
votes

I have the next problem with Data.Sequence and Aeson. I want to create my data DraftVar deriving Generic, which use Data.Sequence on the constructor DV2.

{-# LANGUAGE DeriveGeneric, OverloadedStrings #-}

-- Imports

import Data.Aeson
import GHC.Generics

import qualified Data.Sequence as DS

-- Data

data DraftVar = 
    DV1 { dv1_val :: Int }
    | DV2 { dv2_list :: DS.Seq DraftVar }
    deriving (Show, Generic)

instance ToJSON DraftVar
instance FromJSON DraftVar

With this code, I receive and error that says: No instance for (ToJSON (DS.Seq DraftVar)). So I need to create a instance of Data.Sequence for the Aeson library.

On the ToJSON instance declaration, I decide to transform the Data.Sequence to a list. The code is:

import Data.Foldable as DF

instance (Show a) => ToJSON (DS.Seq a) where
    toJSON l = object [ "values" .=  show (DF.toList l) ]

But what happen, when I want to extract from this Json the list and then transform the data to Data.Sequence?

instance (Show a) => FromJSON (DS.Seq a) where
    parseJSON (Object o) = ???

Maybe I need a library or an special function from Aeson, I don't know. The most useful example (that I found) is this: Parsing an Array with Haskell Aeson

Do you have a better approach?

1
You might also try upgrading; I think aeson has had Seq instances since 0.8.1.0.Ørjan Johansen

1 Answers

3
votes

[] and Seq are isomorphic via fromList / toList (they just have vastly different representations and performance characteristics), so the most straightforward way to implement FromJSON and ToJSON for Seq is by re-using the existing implementation for []:

import qualified Data.Sequence as DS
import Data.Foldable as DF

instance (ToJSON a) => ToJSON (DS.Seq a) where
    toJSON = toJSON . DF.toList

instance (FromJSON a) => FromJSON (DS.Seq a) where
    parseJSON = fmap DS.fromList . parseJSON