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
It would be nice if the following would work. I was surprised that it didn't.
>>> data Dog = MkDog deriving (Generic, Show)
>>> data Cat = MkCat deriving (Generic, Show)
>>> data Duck = MkDuck deriving (Generic, Show)
>>> data Animal = ADog Dog | ACat Cat | ADuck Duck deriving (Generic, Show)
>>> injectSub MkDog :: Animal
<interactive>:7:1: error:
• Couldn't match type ‘'[Duck]’ with ‘'[]’
arising from a functional dependency between:
constraint ‘GIsList (K1 R Duck) (K1 R Duck) '[] '[]’
arising from a use of ‘injectSub’
instance ‘GIsList (Rec0 a) (Rec0 b) '[a] '[b]’
at /home/scottfleischman/GitHub/kcsongor/generic-lens/src/Data/Generics/Product/Internal/HList.hs:111:10-44
• In the expression: injectSub MkDog :: Animal
In an equation for ‘it’: it = injectSub MkDog :: Animal
--|Structural subtyping between sums. A sum 'Sub' is a subtype of another sum
-- 'Sup' if a value of 'Sub' can be given (modulo naming of constructors)
-- whenever a value of 'Sup' is expected. In the running example for instance,
since we can give ADog dog :: Animal given dog :: Dog.
Would it be possible to add this functionality? It would be convenient to simply pass Dog and not have to create a wrapper type data SingleDog = SingleDog Dog when our subtype only has one option.
The existing constructor-renaming behavior works well for creating other subsets of Animal like the following.
>>> data DogOrCat = DCDog Dog | DCCat Cat deriving (Generic, Show)
>>> injectSub (DCDog MkDog) :: Animal
ADog MkDog
However, this renaming of constructors gave me a surprising result with the example code from the SubType module.
Notice the dog changes into a cat! However, it is understandable given that it is effectively renaming the constructor, giving it a name and an age. Yet still surprising that we changed our Dog to a Cat.
If we added the ability I am suggesting, it would be ambiguous in this case whether we want to keep our Dog or change it to a Cat. I'm not sure if it's worth it to try and resolve the ambiguity by a priority or just to have an error in that case?
The text was updated successfully, but these errors were encountered:
It would be nice if the following would work. I was surprised that it didn't.
It seems to fit the definition:
generic-lens/src/Data/Generics/Sum/Subtype.hs
Lines 73 to 75 in 8527fb2
since we can give
ADog dog :: Animal
givendog :: Dog
.Would it be possible to add this functionality? It would be convenient to simply pass
Dog
and not have to create a wrapper typedata SingleDog = SingleDog Dog
when our subtype only has one option.The existing constructor-renaming behavior works well for creating other subsets of
Animal
like the following.However, this renaming of constructors gave me a surprising result with the example code from the SubType module.
generic-lens/src/Data/Generics/Sum/Subtype.hs
Lines 48 to 52 in 8527fb2
generic-lens/src/Data/Generics/Sum/Subtype.hs
Lines 57 to 61 in 8527fb2
Notice the dog changes into a cat! However, it is understandable given that it is effectively renaming the constructor, giving it a name and an age. Yet still surprising that we changed our Dog to a Cat.
If we added the ability I am suggesting, it would be ambiguous in this case whether we want to keep our Dog or change it to a Cat. I'm not sure if it's worth it to try and resolve the ambiguity by a priority or just to have an error in that case?
The text was updated successfully, but these errors were encountered: