user3002631
user3002631

Reputation: 1

Need to make nested json in haskell

At the first time my code worked but without this code :

"decisions" .= object ["texts" .= texts,
                                                                              "liens" .= liens]

And when I try to make a nasted json how you can see in my next code that not worked:

data Decisions = Decisions { texts :: Text,
                             liens :: Int
                 } 
                  deriving Show

data Chap = Chap { titre :: String,
                   image :: String,
                   paragraph :: [Text],
                   decisione :: [Text],
                   link :: [Int],                  
                   battle :: [Text],
                   decisions :: [Decisions]
                 } 
                  deriving Show


instance ToJSON Chap where
     toJSON (Chap titre image paragraph decisione link battle decisions) = object [
                                       "titre" .= titre,
                                       "image" .= image,
                                       "paragraph" .= array paragraph, 
                                       "decisione" .= array decisione,
                                       "link" .= array link,                                       
                                       "battle" .= array battle,
                                       "decisions" .= object ["texts" .= texts,
                                                              "liens" .= liens]                                    
                                       ]

getServiceR :: Int -> Handler Value
getServiceR id  = do 
     returnJson $ extraire $ find (condition id) chapitres
     where
       condition id (idChap, chap) = id == idChap

       extraire Nothing = Chap "" "" [] [] [] [] [[],[]]
       extraire (Just (id,p)) = p


chapitres :: [(Int, Chap)]
chapitres = [
             (1,Chap "Titre 1" "image 1" ["paragraph1", "paragraph11"] ["decisione 1"] [125] ["yes"] [(["turn left"],["5"]) (["turn right"],["15"])]),
             (2,Chap "Titre 2" "image 2" ["paragraph2", "paragraph21"] ["decisione 2"] [125] ["yes"] [["turn left"],["35"]] (["turn right"],["105"])]),
             (3,Chap "Titre 3" "image 3" ["paragraph1", "paragraph11"] ["decisione 1"] [125] ["yes"] [["turn left"],["55"]] ([],[])]),  
        ]

Error which i recive :

Handler\Game.hs:130:758:
    Couldn't match expected type `[a15] -> Decisions'
                with actual type `[a14]'
    The function `[]' is applied to one argument,
    but its type `[a14]' has none
    In the expression: [] []
    In the 7th argument of `Chap', namely `[[] []]'
Build failure, pausing...

Please I need to know a right syntaxe to make the nested jeson in haskell.

Upvotes: 0

Views: 275

Answers (1)

iamnat
iamnat

Reputation: 4166

The 7th argument of the Chap type is [Decisions] and each Decisions is made up of Text Int.

There are two important things:

  • The way Chap declarations are used to create new instances
  • Creating the ToJSON instance for Chap

For nested ToJSON types you must define an instance for each type used within. So if you're defining the ToJSON for Chap define the ToJSON for Decisions first, and the rest will work automatically.

The code sample below compiles successfully. I hope both points are clear enough.

{-# LANGUAGE OverloadedStrings #-}

import Data.Text
import Data.Aeson

data Decisions = Decisions { texts :: Text,
                             liens :: Int 
                 }   
                  deriving Show

data Chap = Chap { titre :: String,
                   image :: String,
                   paragraph :: [Text],
                   decisione :: [Text],
                   link :: [Int],                      
                   battle :: [Text],
                   decisions :: [Decisions]
                 }   
                  deriving Show


instance ToJSON Chap where
     toJSON (Chap titre image paragraph decisione link battle decisions) = object [
                                       "titre" .= titre,
                                       "image" .= image,
                                       "paragraph" .= paragraph, 
                                       "decisione" .= decisione,
                                       "link" .= link,                                           
                                       "battle" .= battle,
                                       "decisions" .= decisions 
                                       ]   
instance ToJSON Decisions where
    toJSON (Decisions texts liens) = object [ "texts" .= texts, "liens" .= liens ]

myChap = Chap "Titre 1" "image 1" ["paragraph1", "paragraph11"] ["decisione 1"] [125] ["yes"] [ (Decisions "turn left" 5),
                                                                                                (Decisions "turn left" 5)
                                                                                              ]   

This code compiles. Loading it into ghci and running

> toJSON myChap

results in

Object fromList [("image",String "image 1"),("battle",Array (fromList [String "yes"])),("decisione",Array (fromList [String "decisione 1"])),("link",Array (fromList [Number 125])),("decisions",Array (fromList [Object fromList [("liens",Number 5),("texts",String "turn left")],Object fromList [("liens",Number 5),("texts",String "turn left")]])),("paragraph",Array (fromList [String "paragraph1",String "paragraph11"])),("titre",String "Titre 1")]

Upvotes: 1

Related Questions