У меня есть объект json с вручную созданным экземпляром ToJSON.Я хотел бы заменить это функцией, которая не требует моего явного перечисления имен ключей.
Я использую "rec *" в качестве префикса, который я хотел бы удалить, и мои поля начинаются как Текствместо строки.
Начиная с минимальных данных:
data R3 = R3 { recCode :: Code
, recValue :: Value} deriving (Show, Generic)
И функция умного конструктора:
makeR3 rawcode rawval = R3 code value where
code = rawcode
value = rawval
Эта реализация работает отлично:
instance ToJSON R3 where
toJSON (R3 recCode recValue) = object [ "code" .= recCode, "value" .= recValue]
Но, как вы можете себе представить, вводить каждое имя ключа вручную из «code» в «recCode» - это не то, что я хочу делать.
tmp_r3 = makeR3 "TD" "100.42"
as_json = encode tmp_r3
main = do
let out = encodeToLazyText tmp_r3
I.putStrLn out
I.writeFile "./so.json" out
return ()
Вывод правильный:
{"value":100.42,"code":"TD"}
-- not recValue and recCode, correct!
Однако, когда я пытаюсь использовать эту функцию, она не может преобразовать текст в строку, как это было раньше автоматически.
instance ToJSON R3 where
toJSON = genericToJSON defaultOptions {
fieldLabelModifier = T.toLower . IHaskellPrelude.drop 3 }
Вывод:
<interactive>:8:35: error:
• Couldn't match type ‘Text’ with ‘String’
Expected type: String -> String
Actual type: String -> Text
• In the ‘fieldLabelModifier’ field of a record
In the first argument of ‘genericToJSON’, namely ‘defaultOptions {fieldLabelModifier = toLower . IHaskellPrelude.drop 3}’
In the expression: genericToJSON defaultOptions {fieldLabelModifier = toLower . IHaskellPrelude.drop 3}
<interactive>:8:47: error:
• Couldn't match type ‘String’ with ‘Text’
Expected type: String -> Text
Actual type: String -> String
• In the second argument of ‘(.)’, namely ‘IHaskellPrelude.drop 3’
In the ‘fieldLabelModifier’ field of a record
In the first argument of ‘genericToJSON’, namely ‘defaultOptions {fieldLabelModifier = toLower . IHaskellPrelude.drop 3}’
Сама ошибкадостаточно ясно, что Text не работает, но что я должен изменить, чтобы функционально удалить свои префиксы из имен ключей в выводе json, а также правильно преобразовать текст в строку?
Я также немного растерялся, что не изменилмой вклад, это был тип текста в бВ других случаях, но первая реализация была в порядке, а вторая - нет.
Я работаю в ноутбуке ihaskell jupyter.
Обновление
Когда яиспользуйте Data.Char, рекомендованный в ответах ниже:
import Data.Char(toLower)
В:
instance ToJSON R3 where
toJSON = genericToJSON defaultOptions {
fieldLabelModifier = Data.Char.toLower . IHaskellPrelude.drop 3 }
Я получаю:
<interactive>:8:35: error:
• Couldn't match type ‘Char’ with ‘String’
Expected type: String -> String
Actual type: String -> Char
• In the ‘fieldLabelModifier’ field of a record
In the first argument of ‘genericToJSON’, namely ‘defaultOptions {fieldLabelModifier = Data.Char.toLower . IHaskellPrelude.drop 3}’
In the expression: genericToJSON defaultOptions {fieldLabelModifier = Data.Char.toLower . IHaskellPrelude.drop 3}
<interactive>:8:55: error:
• Couldn't match type ‘String’ with ‘Char’
Expected type: String -> Char
Actual type: String -> String
• In the second argument of ‘(.)’, namely ‘IHaskellPrelude.drop 3’
In the ‘fieldLabelModifier’ field of a record
In the first argument of ‘genericToJSON’, namely ‘defaultOptions {fieldLabelModifier = Data.Char.toLower . IHaskellPrelude.drop 3}’
И когда я пробую голую "каплю"вместо капли IHaskellPrelude я получаю:
instance ToJSON R3 where
toJSON = genericToJSON defaultOptions {
fieldLabelModifier = Data.Char.toLower . drop 3 }
<interactive>:8:55: error:
Ambiguous occurrence ‘drop’
It could refer to either ‘BS.drop’, imported from ‘Data.ByteString’
or ‘IHaskellPrelude.drop’, imported from ‘Prelude’ (and originally defined in ‘GHC.List’)
or ‘T.drop’, imported from ‘Data.Text’