content: {-# LANGUAGE TypeApplications, ScopedTypeVariables, PolyKinds,
               TypeFamilies, RankNTypes,
               FlexibleContexts #-}
  -- tests about visible type application
  
  module Vta1 where
  
  quad :: a -> b -> c -> d -> (a, b, c, d)
  quad = (,,,)
  
  silly = quad @_ @Bool @Char @_ 5 True 'a' "Hello"
  
  pairup_nosig x y = (x, y)
  
  pairup_sig :: a -> b -> (a,b)
  pairup_sig u w = (u, w)
  
  answer_sig = pairup_sig @Bool @Int False 7 --
  -- (False, 7) :: (Bool, Int)
  
  answer_read = show (read @Int "3") -- "3" :: String
  answer_show = show @Integer (read "5") -- "5" :: String
  answer_showread = show @Int (read @Int "7") -- "7" :: String
  
  intcons a = (:) @Int a
  
  intpair x y = pairup_sig @Int x y
  
  answer_pairup = pairup_sig @Int 5 True -- (5, True) :: (Int, Bool)
  answer_intpair = intpair 1 "hello" -- (1, "hello") :: (Int, String)
  answer_intcons = intcons 7 []      -- [7] :: [Int]
  
  type family F a
  type instance F Char = Bool
  
  g :: F a -> a
  g _ = undefined
  
  f :: Char
  f = g True
  
  answer = g @Char False
  
  mapSame :: forall b. (forall a. a -> a) -> [b] -> [b]
  mapSame _ [] = []
  mapSame fun (x:xs) = fun @b x : (mapSame @b fun xs)
  
  pair :: forall a. a-> (forall b. b -> (a, b))
  pair x y = (x, y)
  
  b = pair @Int 3 @Bool True
  c = mapSame id [1,2,3]
  d = pair 3 @Bool True
  
  pairnum :: forall a. Num a => forall b. b -> (a, b)
  pairnum = pair 3
  
  e = (pair 3 :: forall a. Num a => forall b. b -> (a, b)) @Int @Bool True
  h = pairnum @Int @Bool True
  
  data First (a :: * -> *) = F
  data Proxy (a :: k) = P -- This expands to P (kind variable) (type variable)
  data Three (a :: * -> k -> *) = T
  
  foo :: Proxy a -> Int
  foo _ = 0
  
  first :: First a -> Int
  first _ = 0
  
  fTest = first F
  fMaybe = first @Maybe F
  
  test = foo P
  bar = foo @Bool P -- should work
  
  too :: Three a -> Int
  too _ = 3
  
  threeBase = too T
  threeOk = too @Either T
  
  blah = Nothing @Int
  
  newtype N = MkN { unMkN :: forall a. Show a => a -> String }
  
  n = MkN show
  
  boo = unMkN n @Bool
  
  boo2 :: forall (a :: * -> *) . Proxy a -> Bool
  boo2 _ = False
  
  base = boo2 P
  bar'= boo2 @Maybe P -- should work
  