I'm new in Haskell. Currently I'm working on a SQL project and I got stuck on deserializing JSON file contents. I'm getting some cursed error and I don't know how to fix it.
This is my JSON file:
{
"Table":"flags",
"Columns":[
{"Name":"flag", "ColumnType":"StringType"},
{"Name":"value", "ColumnType":"BoolType"}],
"Rows":[
[{"Value":"StringValue a"}, {"Value":"BoolValue True"}],
[{"Value":"StringValue b"}, {"Value":"BoolValue True"}],
[{"Value":"StringValue b"}, {"Value":"NullValue"}],
[{"Value":"StringValue b"}, {"Value":"BoolValue False"}]
]
}
This is my Haskell code:
data FromJSONColumn = FromJSONColumn {
deserializedName :: String,
deserializedDataType :: String
} deriving (Show, Eq, Generic)
instance FromJSON FromJSONColumn where
parseJSON (Object v) =
FromJSONColumn <$> v .: "Name"
<*> v .: "ColumnType"
parseJSON _ = mzero
This is the error I get:
JSONExample.hs:17:27-32: error:
• Couldn't match type ‘[Char]’ with ‘Key’
Expected: Key
Actual: String
• In the second argument of ‘(.:)’, namely ‘"Name"’
In the second argument of ‘(<$>)’, namely ‘v .: "Name"’
In the first argument of ‘(<*>)’, namely
‘FromJSONColumn <$> v .: "Name"’
|
17 | FromJSONColumn <$> v .: "Name"
| ^^^^^^
JSONExample.hs:18:12-23: error:
• Couldn't match type ‘[Char]’ with ‘Key’
Expected: Key
Actual: String
• In the second argument of ‘(.:)’, namely ‘"ColumnType"’
In the second argument of ‘(<*>)’, namely ‘v .: "ColumnType"’
In the expression:
FromJSONColumn <$> v .: "Name" <*> v .: "ColumnType"
|
18 | <*> v .: "ColumnType"
| ^^^^^^^^^^^^
Could somebody explain how to write instances for such files (files that contain tables) ? How should I do it? I'm truly lost.
P.S. This is the data types I'm working with:
data ColumnType
= IntegerType
| StringType
| BoolType
deriving (Show, Eq)
data Column = Column String ColumnType
deriving (Show, Eq)
data Value
= IntegerValue Integer
| StringValue String
| BoolValue Bool
| NullValue
deriving (Show, Eq)
type Row = [Value]
data DataFrame = DataFrame [Column] [Row]
deriving (Show, Eq)
The second argument to the .:
operator should be of type Key
, but you're passing in a [Char]
(also known as String
). Try one of the following to convert them into a Key
:
Enable the OverloadedStrings
extension. I.e., add {-# LANGUAGE OverloadedStrings #-}
to the top of the source code.
Instead of "Name"
, try fromString "Name"
. Likewise, instead of "ColumnType"
, try fromString "ColumnType"
. fromString
should be imported from the Data.Aeson.Key module. This actually does the same thing as the first option, but the OverloadedStrings
extension does this for you.