content: 
  {-# LANGUAGE BangPatterns #-}
  {-# LANGUAGE DataKinds #-}
  {-# LANGUAGE GADTs #-}
  {-# LANGUAGE LinearTypes #-}
  {-# LANGUAGE MagicHash #-}
  {-# LANGUAGE StandaloneKindSignatures #-}
  {-# LANGUAGE TypeFamilyDependencies #-}
  {-# LANGUAGE UnliftedDatatypes #-}
  
  module EtaExpandDataCon where
  
  import Data.Coerce
  import Data.Kind
  import GHC.Exts
  
  -- Simple eta-expansion tests.
  
  type D1 :: Type -> Type
  data D1 a where
    MkD1 :: Ord a => Float# -> Int -> a %1 -> D1 a
  
  foo1 :: Ord a => Float# -> Int -> a -> D1 a
  foo1 x1 = MkD1 ( x1 `powerFloat#` 1234.0# )
    -- Only the last argument needs us to change the multiplicity,
    -- but this means adding lambdas for intervening arguments:
    -- foo x1 = \ x2 x3 -> MkG x1 x2 x3
  
  type D2 :: Type -> Type -> Type
  data D2 a b where
    MkD2 :: forall a b. a %1 -> b %1 -> a %1 -> D2 a b
  
  foo2 :: forall c d. (c -> c) -> c -> d -> c -> D2 c d
  foo2 very_big arg0 = MkD2 (very_big arg0)
  
  type N3 :: TYPE r -> Type
  newtype N3 a where
    MkN3 :: forall r (a :: TYPE r). (a %1 -> N3 a) %1 -> N3 a
  
  foo3 :: (a %1 -> N3 a) -> N3 a
  foo3 = MkN3
  type D4 :: TYPE FloatRep -> Type -> Type
  data D4 a b = MkD4 a b b
  
  foo4 :: Bool -> Bool -> D4 Float# Bool
  foo4 = MkD4 ( 9.0# `timesFloat#` 17.0# )
  
  -- Nightmare stress test with all features:
  --
  --  - Boxed dictionary and equality constraints
  --  - GADT equality constraints
  --  - unpacking
  --  - levity-polymorphic result kind
  
  data Unpackable = Unpackable Double# Double# Double# Double#
  
  type F :: k -> k
  type family F a = r | r -> a where
  
  type G :: Type -> forall k. k -> Type -> Type -> forall l -> TYPE (BoxedRep l)
  data G a b c d l where
    MkG :: (Ord a, F Int ~ Bool, Coercible (F Bool) Char, Eq x)
        => Float#
        -> {-# UNPACK #-} !Unpackable
        -> {-# UNPACK #-} !Unpackable
     %1 -> a
     %1 -> (a -> x)
     %1 -> x
     %1 -> G a (F b) a Double l
  
  bar :: (F Bool ~ Char, F Int ~ Bool, Ord a)
      => Unpackable
   %1 -> a
      -> (a -> Int)
   %1 -> Int
      -> G a (F b) a Double Unlifted
  bar = MkG 1728.0# (Unpackable 1.0## 2.0## 3.0## 4.0##)
  