I'm trying to avoid writing definitions for toJSON. This is the error I encounter:
Datatypes.hs:92:10:
No instance for (aeson-0.6.0.2:Data.Aeson.Types.Class.GToJSON
(GHC.Generics.Rep (HashMap Key Project)))
arising from a use of `aeson-0.6.0.2:Data.Aeson.Types.Class.$gdmtoJSON'
Possible fix:
add an instance declaration for
(aeson-0.6.0.2:Data.Aeson.Types.Class.GToJSON
(GHC.Generics.Rep (HashMap Key Project)))
In the expression:
(aeson-0.6.0.2:Data.Aeson.Types.Class.$gdmtoJSON)
In an equation for `toJSON':
toJSON = (aeson-0.6.0.2:Data.Aeson.Types.Class.$gdmtoJSON)
In the instance declaration for `ToJSON (HashMap Key Project)'
I get similar errors for all my HashMap data
declarations.
Here's the relevant code. Let me know if there is missing information.
{-# LANGUAGE DeriveGeneric #-} -- for JTask and Fields ToJSON instances:w!
{-# LANGUAGE DeriveDataTypeable #-} -- This may be needed for HashMaps
{-# LANGUAGE FlexibleInstances #-} -- for the HashMap ToJSON instances
{-# LANGUAGE DefaultSignatures #-}
import Prelude
import Data.ByteString
import GHC.Generics (Generic )
import Data.Data
import Data.Typeable (Typeable) -- fix HashMap ToJSON instances? maybe
import Data.Aeson
import Data.Aeson.Generic
import Data.Aeson.Types -- (ToJSON,FromJSON)
import Data.HashMap.Strict (HashMap)
data JTask = JTask {fields :: Fields} deriving (Typeable,Data,Generic)
data Fields = Fields { project :: HashMap Key Project
, summary :: ByteString
, issuetype :: HashMap Name Task
, versions :: [HashMap Name Version]
, description :: ByteString
} deriving (Typeable,Data,Generic)
data Key = Key deriving (Typeable,Data,Generic)
instance Show Key where
show Key = "key"
data Name = Name deriving (Typeable,Data,Generic)
instance Show Name where
show Name = "name"
data Task = Task deriving (Typeable,Data,Generic)
type Version = ByteString -- Placeholder type. Probably using Day for realsies.
data Project = BNAP deriving (Typeable,Data,Generic) -- Fill this out as we go
instance Generic (HashMap Key Project)
instance Data (HashMap Key Project)
--instance GToJSON (HashMap Key Project)
instance Generic (HashMap Name ByteString)
instance Data (HashMap Name ByteString)
instance Generic (HashMap Name Task)
instance Data (HashMap Name Task)
-- JSON instances
instance ToJSON CreateError
instance ToJSON Fields
instance ToJSON JTask
instance ToJSON Key
instance ToJSON Name
instance ToJSON Task
instance ToJSON Project
instance ToJSON (HashMap Key Project)
instance ToJSON (HashMap Name Task)
instance ToJSON (HashMap Name ByteString)
-- instance ToJSON Version uncomment when we change Version's type.
I cannot make an instance for Data.Aeson.Types.Class.GToJSON
because Data.Aeson.Types.Class
is not exported. What are my options? What will I have to write manually? Is deriveJSON
the best choice?
Update:
I implemented the suggestion below.
Here's the code
createObject :: CreateConf -> ResourceT IO Value
createObject (CreateConf iSummary iDesc dd) = do
let jfields = Fields {project = singleton Key BNAP
,summary = iSummary
,issuetype = singleton Name Task
,versions = [singleton Name (calcVersion dd)]
,description = iDesc
}
return $ toJSON (JTask jfields)
The first instance yields Object fromList [("key",Array (fromList []))])
Second instance yields Object fromList [("name",Array (fromList []))]
any idea why name
and key
are empty?
How could I find out?
Would it be easier to just use deriveJSON
.
update:
Thanks to help from NathanHowell the more important problem has been solved, which is the GToJSON instance for unary types. The solution was to make my own instances for the unary types. The JSON objects are out of order, but I don't know if that matters. If it does, it seems another manual ToJSON instance for Fields would fix that.
update:
Okay a little context. I'm writing a JIRA front-end. I mention that because people in the future may come here to discover the following good news: JIRA doesn't care about Object order.