I've got the following data type definition:
type DynamicF' :: k -> (k -> Type) -> Type
data DynamicF' k f where
DynamicF :: Typeable a => f a -> DynamicF' k f
The thing is, generally, I'm going to be specialising k to Type. So I've provided the following type alias:
type DynamicF f = DynamicF' Type f
Then I can do things like this:
data Showable a where
Showable :: Show a => a -> Showable a
f :: DynamicF Showable -> String
f (DynamicF @_ @a x) = g x where
g :: Showable a -> String
g (Showable y) = show y
This is perhaps a silly example but hopefully illustrative, but notice the pattern match:
DynamicF @_ @a x
And in particular, the underscore required for the first argument.
This is because the first type application argument seems to be against f, not a, in the DynamicF constructor.
Apparently I can change the order of these using forall blah., and perhaps using forall {blah}. like constructs.
But I'm not sure where to actually put the forall.s in this code so they I can instead just do:
f (DynamicF @a x)
in the pattern match, instead of requiring the silly underscore.
The right place to put the
forallis in thedatadeclaration:If you were concerned that somehow the
fandkcouldn't be specified in aforallbecause they are part of theDynamicF' k ftype, don't be. It is the type of the "result" of the constructor that determines what variables become part of the final type. For example, the following declaration works exactly like your original:However, note that I wasn't able to duplicate your issue. The order was already
forall a f kfor this constructor (because theTypeable a =>putsain first position).