Reputation: 2581
I am able to json-encode my data
import Data.Aeson (ToJSON, toJSON, (.=), object)
import qualified Data.Text as T
import qualified Data.Text.Lazy as L
data ServiceResponse = ReadServiceResponse L.Text
| GenericServiceError Int L.Text
instance ToJSON ServiceResponse where
toJSON (ReadServiceResponse text) = object ["text" .= text]
toJSON (GenericServiceError code text) =
object ["code" .= code, "message" .= text]
For data having only one "scalar" value (e.g. String, Int, L.Text, ...) I would like to get a scalar representation instead of an object. For example the ReadServiceResponse
should be encoded into a json string instead of an object like
{
text: "hi I'm some text."
}
I tried
instance ToJSON ServiceResponse where
toJSON (ReadServiceResponse text) = text
which does not compile
• Couldn't match expected type ‘aeson-1.3.1.1:Data.Aeson.Types.Internal.Value’ with actual type ‘L.Text’
Should I transform text
into a Data.Aeson.Types.Internal.Value
(How can i do that)? Thanks in advance for any help
Upvotes: 0
Views: 148
Reputation: 531315
Since toJSON
must return a value of type Value
, you can't return text
by itself; it has to be wrapped with the String
data constructor.
toJSON (ReadServiceResponse text) = String text
Note that since String :: T.Text -> Value
, this requires you to use the strict implementation of Text
in the definition of ReadServiceResopnse
:
data ServiceResponse = ReadServiceResponse T.Text -- not L.Text
| GenericServiceError Int L.Text
or doing a conversion in toJSON
:
toJSON (ReadServiceResponse text) = String . T.pack . L.unpack $ text
Upvotes: 2