Question

I have something similar to this class in my code. It does not make sense for my situation to add a' as another parameter to class Foo.

class Foo a where
    type FCtx a a' :: Constraint
    type FCtx a a' = ()

    f :: (FCtx a a') => a -> a'

data D b = D b

instance (Integral b) => Foo (D b) where
    -- the next line does not compile because b' does not appear on the LHS
    type FCtx (D b) a' = (a' ~ D b', Integral b') 

    f (D x) = D $ fromIntegral x

For this specific instance of Foo, I want a' to be related in this way. The only way I've come up with to make this work is by adding a "dummy" class with an "obvious" type synonym:

class DClass d where
   type DType d

instance DClass (D b) where
    type DType (D b) = b

The Foo instance now becomes:

instance (Integral b) => Foo (D b) where
    type FCtx (D b) a' = (a' ~ D (DType a'), Integral (DType a'))
    f (D x) = D $ fromIntegral x

The problem is that I had to create an entire class (and instance) for my specific data type just to express the type synonym/functional dependency that (D b) determines b. I will not have any other instances of this class, because I always want DType a' to mean the type parameter to D b.

What I would like to do instead is something like:

type DParam (D b) = b

instance (Integral b) => Foo (D b) where
     type FCtx (D b) a' = (a' ~ D (DParam a'), Integral (DParam a'))
     f (D x) = D $ fromIntegral x

or maybe even some nicer way of expressing this Constraint without using type synonyms at all. It seems silly that I should be forced to create an (open) class with a type synonym with a single instance just to accomplish this, and unsafe that others could potentially create new instances that I did not intend.

At the least, would there not be some canonical way of turning a "pattern matched type synonym" into the class/instance DClass above?

Was it helpful?

Solution

Slightly lighter weight, using type families:

type family DParam d :: *
type instance DParam (D b) = b

Not sure if you can do much better right now...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top