-
Notifications
You must be signed in to change notification settings - Fork 5
Description
It seems like the functionality of some functions like fromF
depends on the fact that the Generic
representation of a type is equivalent to its' Bounded
/Enum
representation (through the Count
type family), which in general can be not true.
There isn't really a good way of representing the link between Bounded
/Enum
and Count
in haskell.
The problem I have with this is that it is not explicitly mentioned anywhere in the documentation and can break things in unexpected ways. (If a type has a custom Enum
or Bounded
instance for some reason)
I think it can be beneficial to expose the ability to define a custom Count
instance for arbitrary types to the user.
An approach can be to make Count
an open type family. This would most likely require us to remove the base Count d = Count (Rep d R)
case, making the user explicitly define an instance of the type family for every type he wants to use as the matrix index.
We could also expose some GenericCount
, which would make implementing the removed base case for custom types easier and more idiomatic.
Another thought I have it to make the Count
type family not a type family at all and make it a functional dependency in a typeclass, which encapsulates the conversion between the custom type and the Either
/()
representation.
class MatIndex t (i :: Nat) | t -> i where
toIndex :: t -> FromNat i
fromIndex :: FromNat i -> t
This would allow us to completely remove the implicit requirement between the Generic
and Enum
/Bounded
instances. (Although it would still be used in a default implementation of the typeclass, but the connection can be made explicit by making a newtype
, which can be used to derive the the typeclass: deriving MatIndex via MatBoundedIndex
).
This would remove the "hacky" part of fromF
which uses the Enum
and Bounded
instances explicitly.