Evil idea: Allow empty record field update syntax for types.
Use case: Visible type application.
I often work with constructors with many arguments that I want to instantiate type variables with:
show @(Vector _ _)
:: Show a => Vector n a -> String
-- Type arguments reversed, see https://github.com/ekmett/distributive/pull/18
cotraverse @_ @(Vector _)
:: (NATTY n, Functor f) => (f a -> b) -> (f (Vector n a) -> Vector n a')
fmap @(Bazaar _ _ _)
:: (t -> t') -> (Bazaar p a b t -> Bazaar p a b t')
show @(Magma _ _ _ _)
:: (Show a, Show i) => Magma i t b a -> String
This makes no sense since types have nothing to do with record or updates thereof but that syntax is often used to avoid parentheses and unneeded wildcard arguments:
isBar (Bar _ _ _ _ _) = True
-- ===>
isBar Bar{} = True
This also means you don't need to worry about the kind of your constructor wrt the type (class) variable it instantiates.
Thus the proposal is to allow:
show @Vector{}
:: Show a => Vector n a -> String
cotraverse @_ @Vector{}
:: (NATTY n, Functor f) => (f a -> b) -> (f (Vector n a) -> Vector n a')
fmap @Bazaar{}
:: (t -> t') -> (Bazaar p a b t -> Bazaar p a b t')
show @Magma{}
:: (Show a, Show i) => Magma i t b a -> String
This would save quite a few keystrokes in my daily coding but more importantly it saves cognitive load but I expect raised eyebrows (especially since GHC would have to determine whether to interpret show @Vector{}
as show @Vector
, show @(Vector _n)
or show @(Vector _n _a)
).