Skip to content

Correctness of bindS #25

@bolt12

Description

@bolt12

I've been thinking about the correctness of bindS and if there was any way to prove that if for a data type a, (Bounded a, Enum a) are well defined than the following holds:

natVal (Proxy :: Proxy (Count a)) == length [minBound .. maxBound]

(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 a Selective 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 and Enum correctly. For example one could have the following instances:

data Const1 = One | Two deriving (Show)

instance Bounded Const1 where
  minBound = One
  maxBound = One

instance Enum Const1 where
  toEnum _ = One

  fromEnum One = 1
  fromEnum Two = 2

For this type instances [minBound..] would give an infinite list of Ones 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 also genum has all possible inhabitants of a, 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, function bindS is correct.

I tried to work on a PR but it boils down to changing casesEnum for casesGEnum :: GEnum a => Cases a and I was not able to get rid of the partial fromRight on bindS, 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 :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions