{-# 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##)