You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Consider a polymorphic type data T a = T [a], where the parameter is used in a list. The generically-derived instance ToSchema (T Char) agrees with ToJSON (encodes as a string), but the polymorphic version instance ToSchema (T a) does not (when used at a ~ Char -- it encodes as an array of "characters" i.e. length-1 strings.).
A complete example
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
module Main where
import Data.Aeson
import Data.OpenApi
import GHC.Generics
data Poly a = Poly [a]
deriving (Generic,Show)
data Mono a = Mono [a]
deriving (Generic,Show)
instance ToJSON a => ToJSON (Poly a)
instance ToSchema a => ToSchema (Poly a)
instance ToJSON (Mono Char)
instance ToSchema (Mono Char)
main :: IO ()
main = do
putStrLn "Testing monomorphic instance"
go $ Mono "foo"
putStrLn ""
putStrLn "Testing polymorphic instance"
go $ Poly "foo"
where
go x = do
case validatePrettyToJSON x of
Nothing -> putStrLn "validation passed"
Just err -> putStrLn "validation FAILED" >> putStrLn err
which results in
Testing monomorphic instance
validation passed
Testing polymorphic instance
validation FAILED
Validation against the schema fails:
* expected JSON value of type OpenApiArray
JSON value:
"foo"
Swagger Schema:
{
"items": {
"example": "?",
"maxLength": 1,
"minLength": 1,
"type": "string"
},
"type": "array"
}
Swagger Description Context:
{}
This is presumably because openapi3 and aeson handle the special case of [Char] differently.
(There may be some other such cases that differ -- I have not looked further. #50 is perhaps related.)
The text was updated successfully, but these errors were encountered:
I fear that once instance ToSchema (Poly a) is generated, there is no way to "look" at concrete instantiations of a. Some horrible magic is required to get it right.
Is this case important for you, or just a peculiarity?
Is this case important for you, or just a peculiarity?
I ran across this problem in a real project. Thankfully I can work around this bug by listing out the particular monomorphic instances I need.
I fear that once instance ToSchema (Poly a) is generated, there is no way to "look" at concrete instantiations of a. Some horrible magic is required to get it right.
Sure, you cannot "look" in this way. We could (with only a slightly more complex class) generate the correct polymorphic instance in the first place. The way this tends to be done (e.g. aeson and base's Show) is to add an extra member to the class toJSONList :: [a] -> Value, showList :: [a] -> [ShowS] which is then used in the general instance C a => instance C [a]. (Note that this extra member can have a default definition, so there is no extra burden when defining members of the class, unless one wants to handle lists peculiarly).
(Perhaps this is what you meant by "horrible magic"?)
Consider a polymorphic type
data T a = T [a]
, where the parameter is used in a list. The generically-derivedinstance ToSchema (T Char)
agrees withToJSON
(encodes as a string), but the polymorphic versioninstance ToSchema (T a)
does not (when used ata ~ Char
-- it encodes as an array of "characters" i.e. length-1 strings.).A complete example
which results in
This is presumably because openapi3 and aeson handle the special case of
[Char]
differently.(There may be some other such cases that differ -- I have not looked further. #50 is perhaps related.)
The text was updated successfully, but these errors were encountered: