-
Notifications
You must be signed in to change notification settings - Fork 21
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
Correctness of bindS
#25
Comments
I made something that mimicks in a simpler way what generic-deriving does but without the fairness in the case of the List type: |
@bolt12 Many thanks for sharing your thoughts and experiments! I agree with your conclusion: we can't really prove much without assuming that instances are lawful. In the next few weeks, I'm planning to introduce some changes to the selective/src/Control/Selective/Multi.hs Lines 151 to 152 in 4f378fe
After these changes, selective/src/Control/Selective/Multi.hs Lines 171 to 172 in 4f378fe
So, I suggest not to do any changes to |
Very cool! So basically you have generalization of Coproducts (or types with tags/disjunctive unions) and defend that if you have a computation that produces a value with a tag you can I really liked the parallel you do with the And I noticed that you still need This is interesting and I wonder what type of changes are you going to introduce, are you going to replace (Regarding
|
Thank you, glad you liked it :-)
For now, I'd like to stick to
My current plan is to add the method
It comes from the
Yes! The only difference is that now if you statically see a match with N branches, you can decide if you really want to speculatively execute all N branches, knowing that only one of them is going to be needed in the end. Perhaps, it makes sense to speculate only for small values of N. |
Awesome, got it! Thank you 😄 |
I've been thinking about the correctness of
bindS
and if there was any way to prove that if for a data typea
,(Bounded a, Enum a)
are well defined than the following holds:(where
Count
can be a type-family similar to the one I use in my LAoP library, that counts all possible inhabitants of a data type)Or even better: ensure that all the possible inhabitants of
a
are present in[minBound .. maxBound]
or[minBound ..]
, we could safely say that under this restrictions aSelective
is equivalent to a (less efficient)Monad
.The problem is that we cannot assure that an end user, for some custom type, will implement
Bounded
andEnum
correctly. For example one could have the following instances:For this type instances
[minBound..]
would give an infinite list ofOne
s and[minBound .. maxBound]
would give the list[One]
. We cannot rely on the end user to provide type instances that compel with the semantic we are looking for...I guess that if the instances are derived by GHC one can assume they're at least correct wrt the semantics we are looking for, right? With this in mind I found generic-deriving and I think it pretty much offers the invariants we are looking for:
GEnum a
respects |a
|== length genum
and alsogenum
has all possible inhabitants ofa
, through generics. This is good because we are not limited to(Enum a, Bounded a)
constraints, which GHC can only derive for data types which have one or more nullary constructors. Which means that, unless someone overwrites the type instance, functionbindS
is correct.I tried to work on a PR but it boils down to changing
casesEnum
forcasesGEnum :: GEnum a => Cases a
and I was not able to get rid of the partialfromRight
onbindS
, although I am confident that we can assure that it will not fail.What do you think about this @snowleopard ? This is are all informal claims but can be seen as a step forward :)
The text was updated successfully, but these errors were encountered: