-
Notifications
You must be signed in to change notification settings - Fork 329
Add lifted typeclasses and some instances #381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I'm working on the GHC generics and TH support for these classes, and I've hit a bit of a stumbling block. I need to have generalized versions of |
@RyanGlScott |
That sounds good. Another thorny issue: I need to lift the class KeyValue kv where
(.=) :: ToJSON v => Text -> v -> kv
class KeyValue1 kv where
liftedKeyValue :: ToJSON1 f => (v -> Value) -> Text -> f v -> kv
class KeyValue2 kv where
liftedKeyValue2 :: ToJSON2 f => (v1 -> Value) -> (v2 -> Value)
-> Text -> f v1 v2 -> kv With these, we can make instances for instance KeyValue Pair where
name .= value = keyValuePair toJSON name value
instance KeyValue1 Pair where
liftedKeyValue tj name value = keyValuePair (liftToJSON tj) name value
instance KeyValue2 Pair where
liftedKeyValue2 tj1 tj2 name value =
keyValuePair (liftToJSON2 tj1 tj2) name value
keyValuePair :: (v -> Value) -> Text -> v -> Pair
keyValuePair tj name value = (name, tj value) But it's not quite as straightforward to make instance KeyValue Series where
name .= value = Value . Encoding $
E.text name <> B.char7 ':' <> builder value Instead of using
class ToJSON1 f where
liftToJSON :: (a -> Value) -> (a -> Encoding) -> f a -> Value
liftToEncoding :: (a -> Value) -> (a -> Encoding) -> f a -> Encoding
class ToJSON2 f where
liftToJSON2 :: (a -> Value) -> (a -> Encoding) -> (b -> Value) -> (b -> Encoding) -> f a b -> Value
liftToEncoding2 :: (a -> Value) -> (a -> Encoding) -> (b -> Value) -> (b -> Encoding) -> f a b -> Encoding And update |
@RyanGlScott do you really need |
You're right, it would probably be far easier to just hardcode the key-value pair functionality I need in But we're not in the clear yet, I'm afraid. I just spotted this in -- Infix constructors.
argsToEncoding opts multiCons (InfixC _ conName _) = do
al <- newName "argL"
ar <- newName "argR"
match (infixP (varP al) conName (varP ar))
( normalB
$ sumToEncoding opts multiCons conName
$ [|toEncoding|] `appE` listE [ [|toJSON|] `appE` varE a
| a <- [al,ar]
]
)
[]
|
AFAICS I made all instances, except for the map types. Would add them as part of #341. Review is welcome. |
@phadej Thanks for writing all those instances. I'd also like to see instances for
Clearly, most of these are bad candidates for |
Hm, I think I answered my own question above. We can't replace toEncoding [toEncoding a, toEncoding b] And @phadej, I'm afraid the only way to do this right is to change |
Sorry, on mobile atm. I'd say that changing typeclasses only to benefit generic derivatona is a bad excuse. And it also doesn't make sense for |
@andrewthad there aren't instances for those types, but the ones which makes sense to have instances: yes, but I'd rather have them in separate PR |
@phadej, I agree that it seems a bit funny, which is why I asked if perhaps we should be doing something besides splicing in |
@phadej That sounds good. I'll wait to PR the other instances until this one goes through. |
@RyanGlScott I can barely read or write TH, but I think that the existing TH
Which converts
I think it should be changed to do generate this instead. If I understand correctly, that would also solve the problems you are having with writing a lifted version of it. |
Thanks @andrewthad, that sounds like a much more reasonable approach. I've made a PR to @phadej's PR here which implements TH and generics support: phadej#1 |
If there is any more discussion to be had here, it's probably better to discuss it on #391, which includes all commits in this PR. |
Close in favour of #391 |
WIP, have to add rest of the instances. That should be straightforward. Comments are welcome.
Resolves #352