Let's say we have the following data:
hobby :: { name :: String }
hobby = { name: "Football" }Before visible type applications we could write this:
newHobby = Lens.set (prop (Proxy :: Proxy "name")) "PureScript" hobbyNow we can write this:
newHobby = Lens.set (propVTA @"name") "PureScript" hobbyAnother example is with variants:
myVariant = inj (Proxy :: Proxy "variantName") "variantValue"Becomes
myVariant = injVTA @"variantName" "variantValue"
An easy way to write propVTA as kind of an adapter is the following:
propVTA :: forall @a r. Lens' r a 
propVTA = prop (Proxy :: Proxy a)The interesting and new bit is the @ sign before the a which allows
people calling our propVTA function to specify a concrete (monomorphic)
type for the general a type variable as we did in propVTA @"name".
The simplest example of a function that takes a VTA is the following:
vtaIdentity :: forall @a. a -> a
vtaIdentity v = vAt the call-site would then be vtaIdentity @Int 5 or vtaIdentity @Boolean false, etc.
When you have multiple @ signs in the forall bit of your function definition
their order matters. We will demonstrate this with the help of a function that
renames a record field:
Example:
x = { boringName: "value" }
y = renameVTA @"boringName" @"excitingName" x
renameVTA :: forall @oldName @newName rec1 rec2. 
   IsSymbol oldName =>
   IsSymbol newName =>
   -- Some constraints elided for simplicity
   {|rec1} -> 
   {|rec2}
renameVTA = unsafeRename 
  (reflectSymbol :: (Proxy :: Proxy oldName)) 
  (reflectSymbol :: (Proxy :: Proxy newName))In some cases you will still need to require Proxys in your APIs.
But at least now you can define a helper function
prx :: forall @a. Proxy a
prx = ProxyAnd then write
foo = myFn (prx @"Help")
Or even
applyProxy :: forall @p a. (Proxy p -> a -> b) -> a -> b
applyProxy fn x = fn (Proxy :: Proxy p) b
infixl 2 applyProxy as @$And then
foo = myFn @$ @"Something" @$ @Int 24