I have this datatype
newtype Dimension a b = MkDimension b
Whenever it is properly formatted (e.g. satisfies the format constraint), I want to derive a set of classes. I do not want a Dimension which does not satisfy the format constraint to be created.
This also means that if I do this:
newtype Dimension a b = MkDimension b
deriving newtype Num
fromIntegral is still capable of producing dimensions which are improperly formatted. What should I do? I want to also derive applicative, monoid, and others which would all give the opportunity to create invalid dimension values.
Details: To ensure that ordering doesn't matter when adding dimensions, I attempted to ensure that a Dimension would never have anything to the 0, and would be fully sorted (e.g. (MkDimension 2 :: Dimension '[ '("Meter",0)] Int) + (MkDimension 4 :: Dimension '[] Int)) would be bad, as they are the same dimension, but we would get a type-error. More realistically, the types could be in the wrong order, also causing an error. (MkDimension 2 :: Dimension '[ '("Meter",1),'("Foot",1)] Int) + (MkDimension 4 :: Dimension '[ '("Foot",1),'("Meter",1)] Int). To stop both of those, I want to make it so that fromIntegral is only allowed on properly formatted dimensions.
type family Has0 a where
Has0 '[] = 'False
Has0 '(_,0) ': _ = 'True
Has0 _ ': b = Has0 b
type Format a = (a ~ Sort a, Has0 a ~ 'False)
The definition of sort is too long to fit in here.
Dimensionrepresents. It's hard to answer right now. Generally, I would recommend to avoid the temptation to derive All tEh kLaSseS for your custom data types, and in particular notNum. People do that all to often, and it subverts the whole point of having a strong type system that makes it easy to get just the right results, instead of weird unexpected behaviour.formatconstraint" means. But in general I doubt thatderivingis going to be sufficient for you; you will almost certainly have to do those derivations manually.Numinstance - it would be completely the wrong interface. Instead, you should implementVectorSpaceplus a custom multiplication, that takes care so e.g. the product of two lengths is an area (different type).