Skip to content

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)).

Edited by Icelandjack
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information