Skip to content

Commit

Permalink
Don't defunctionalize helpers for class defaults or instance methods
Browse files Browse the repository at this point in the history
`singletons-th` generates "helper" type families that contain the definitions
of class method defaults or instance methods. For example, this:

```hs
class C a where
  m :: a -> b -> a
  m x _ = x
```

Will be promoted to this:

```hs
class PC a where
  type M (x :: a) (y :: b) :: a
  type M x y = MHelperSym0 `Apply` x `Apply` y

type MHelper :: a -> b -> a
type family MHelper x y where
  MHelper x _ = x

type MHelperSym0 :: a ~> b ~> a
type MHelperSym1 :: a -> b ~> a
...
```

Generating defunctionalization symbols for `MHelper` is wasteful, however, as
we never really _need_ to partially apply `MHelper`. Instead, we can just
generate this code:

```hs
class PC a where
  type M (x :: a) (y :: b) :: a
  type M x y = MHelper x y
```

This takes advantage of the fact that when we apply `MHelper`, we always fully
apply it to all of its arguments. This means that we can avoid generating
defunctionalization symbols for helper type families altogether, which is a
nice optimization.

This patch implements that idea, fixing #608 in the process.
  • Loading branch information
RyanGlScott committed Jun 19, 2024
1 parent f44bf07 commit 553e250
Show file tree
Hide file tree
Showing 37 changed files with 150 additions and 2,485 deletions.
162 changes: 6 additions & 156 deletions singletons-base/tests/compile-and-dump/GradingClient/Database.golden

Large diffs are not rendered by default.

23 changes: 1 addition & 22 deletions singletons-base/tests/compile-and-dump/Promote/Newtypes.golden
Original file line number Diff line number Diff line change
Expand Up @@ -48,26 +48,5 @@ Promote/Newtypes.hs:(0,0)-(0,0): Splicing declarations
type TFHelper_0123456789876543210 :: Foo -> Foo -> Bool
type family TFHelper_0123456789876543210 (a :: Foo) (a :: Foo) :: Bool where
TFHelper_0123456789876543210 (Foo a_0123456789876543210) (Foo b_0123456789876543210) = Apply (Apply (==@#@$) a_0123456789876543210) b_0123456789876543210
type TFHelper_0123456789876543210Sym0 :: (~>) Foo ((~>) Foo Bool)
data TFHelper_0123456789876543210Sym0 :: (~>) Foo ((~>) Foo Bool)
where
TFHelper_0123456789876543210Sym0KindInference :: SameKind (Apply TFHelper_0123456789876543210Sym0 arg) (TFHelper_0123456789876543210Sym1 arg) =>
TFHelper_0123456789876543210Sym0 a0123456789876543210
type instance Apply @Foo @((~>) Foo Bool) TFHelper_0123456789876543210Sym0 a0123456789876543210 = TFHelper_0123456789876543210Sym1 a0123456789876543210
instance SuppressUnusedWarnings TFHelper_0123456789876543210Sym0 where
suppressUnusedWarnings
= snd ((,) TFHelper_0123456789876543210Sym0KindInference ())
type TFHelper_0123456789876543210Sym1 :: Foo -> (~>) Foo Bool
data TFHelper_0123456789876543210Sym1 (a0123456789876543210 :: Foo) :: (~>) Foo Bool
where
TFHelper_0123456789876543210Sym1KindInference :: SameKind (Apply (TFHelper_0123456789876543210Sym1 a0123456789876543210) arg) (TFHelper_0123456789876543210Sym2 a0123456789876543210 arg) =>
TFHelper_0123456789876543210Sym1 a0123456789876543210 a0123456789876543210
type instance Apply @Foo @Bool (TFHelper_0123456789876543210Sym1 a0123456789876543210) a0123456789876543210 = TFHelper_0123456789876543210 a0123456789876543210 a0123456789876543210
instance SuppressUnusedWarnings (TFHelper_0123456789876543210Sym1 a0123456789876543210) where
suppressUnusedWarnings
= snd ((,) TFHelper_0123456789876543210Sym1KindInference ())
type TFHelper_0123456789876543210Sym2 :: Foo -> Foo -> Bool
type family TFHelper_0123456789876543210Sym2 (a0123456789876543210 :: Foo) (a0123456789876543210 :: Foo) :: Bool where
TFHelper_0123456789876543210Sym2 a0123456789876543210 a0123456789876543210 = TFHelper_0123456789876543210 a0123456789876543210 a0123456789876543210
instance PEq Foo where
type (==) a a = Apply (Apply TFHelper_0123456789876543210Sym0 a) a
type (==) a a = TFHelper_0123456789876543210 a a
Original file line number Diff line number Diff line change
Expand Up @@ -88,78 +88,48 @@ Singletons/BoundedDeriving.hs:(0,0)-(0,0): Splicing declarations
type MinBound_0123456789876543210 :: Foo1
type family MinBound_0123456789876543210 :: Foo1 where
MinBound_0123456789876543210 = Foo1Sym0
type MinBound_0123456789876543210Sym0 :: Foo1
type family MinBound_0123456789876543210Sym0 :: Foo1 where
MinBound_0123456789876543210Sym0 = MinBound_0123456789876543210
type MaxBound_0123456789876543210 :: Foo1
type family MaxBound_0123456789876543210 :: Foo1 where
MaxBound_0123456789876543210 = Foo1Sym0
type MaxBound_0123456789876543210Sym0 :: Foo1
type family MaxBound_0123456789876543210Sym0 :: Foo1 where
MaxBound_0123456789876543210Sym0 = MaxBound_0123456789876543210
instance PBounded Foo1 where
type MinBound = MinBound_0123456789876543210Sym0
type MaxBound = MaxBound_0123456789876543210Sym0
type MinBound = MinBound_0123456789876543210
type MaxBound = MaxBound_0123456789876543210
type MinBound_0123456789876543210 :: Foo2
type family MinBound_0123456789876543210 :: Foo2 where
MinBound_0123456789876543210 = ASym0
type MinBound_0123456789876543210Sym0 :: Foo2
type family MinBound_0123456789876543210Sym0 :: Foo2 where
MinBound_0123456789876543210Sym0 = MinBound_0123456789876543210
type MaxBound_0123456789876543210 :: Foo2
type family MaxBound_0123456789876543210 :: Foo2 where
MaxBound_0123456789876543210 = ESym0
type MaxBound_0123456789876543210Sym0 :: Foo2
type family MaxBound_0123456789876543210Sym0 :: Foo2 where
MaxBound_0123456789876543210Sym0 = MaxBound_0123456789876543210
instance PBounded Foo2 where
type MinBound = MinBound_0123456789876543210Sym0
type MaxBound = MaxBound_0123456789876543210Sym0
type MinBound = MinBound_0123456789876543210
type MaxBound = MaxBound_0123456789876543210
type MinBound_0123456789876543210 :: forall a. Foo3 a
type family MinBound_0123456789876543210 @a :: Foo3 a where
MinBound_0123456789876543210 @a = Apply Foo3Sym0 MinBoundSym0
type MinBound_0123456789876543210Sym0 :: forall a. Foo3 a
type family MinBound_0123456789876543210Sym0 @a :: Foo3 a where
MinBound_0123456789876543210Sym0 = MinBound_0123456789876543210
type MaxBound_0123456789876543210 :: forall a. Foo3 a
type family MaxBound_0123456789876543210 @a :: Foo3 a where
MaxBound_0123456789876543210 @a = Apply Foo3Sym0 MaxBoundSym0
type MaxBound_0123456789876543210Sym0 :: forall a. Foo3 a
type family MaxBound_0123456789876543210Sym0 @a :: Foo3 a where
MaxBound_0123456789876543210Sym0 = MaxBound_0123456789876543210
instance PBounded (Foo3 a) where
type MinBound = MinBound_0123456789876543210Sym0
type MaxBound = MaxBound_0123456789876543210Sym0
type MinBound = MinBound_0123456789876543210
type MaxBound = MaxBound_0123456789876543210
type MinBound_0123456789876543210 :: forall a b. Foo4 a b
type family MinBound_0123456789876543210 @a @b :: Foo4 a b where
MinBound_0123456789876543210 @a @b = Foo41Sym0
type MinBound_0123456789876543210Sym0 :: forall a b. Foo4 a b
type family MinBound_0123456789876543210Sym0 @a @b :: Foo4 a b where
MinBound_0123456789876543210Sym0 = MinBound_0123456789876543210
type MaxBound_0123456789876543210 :: forall a b. Foo4 a b
type family MaxBound_0123456789876543210 @a @b :: Foo4 a b where
MaxBound_0123456789876543210 @a @b = Foo42Sym0
type MaxBound_0123456789876543210Sym0 :: forall a b. Foo4 a b
type family MaxBound_0123456789876543210Sym0 @a @b :: Foo4 a b where
MaxBound_0123456789876543210Sym0 = MaxBound_0123456789876543210
instance PBounded (Foo4 a b) where
type MinBound = MinBound_0123456789876543210Sym0
type MaxBound = MaxBound_0123456789876543210Sym0
type MinBound = MinBound_0123456789876543210
type MaxBound = MaxBound_0123456789876543210
type MinBound_0123456789876543210 :: Pair
type family MinBound_0123456789876543210 :: Pair where
MinBound_0123456789876543210 = Apply (Apply PairSym0 MinBoundSym0) MinBoundSym0
type MinBound_0123456789876543210Sym0 :: Pair
type family MinBound_0123456789876543210Sym0 :: Pair where
MinBound_0123456789876543210Sym0 = MinBound_0123456789876543210
type MaxBound_0123456789876543210 :: Pair
type family MaxBound_0123456789876543210 :: Pair where
MaxBound_0123456789876543210 = Apply (Apply PairSym0 MaxBoundSym0) MaxBoundSym0
type MaxBound_0123456789876543210Sym0 :: Pair
type family MaxBound_0123456789876543210Sym0 :: Pair where
MaxBound_0123456789876543210Sym0 = MaxBound_0123456789876543210
instance PBounded Pair where
type MinBound = MinBound_0123456789876543210Sym0
type MaxBound = MaxBound_0123456789876543210Sym0
type MinBound = MinBound_0123456789876543210
type MaxBound = MaxBound_0123456789876543210
data SFoo1 :: Foo1 -> Type where SFoo1 :: SFoo1 (Foo1 :: Foo1)
type instance Sing @Foo1 = SFoo1
instance SingKind Foo1 where
Expand Down
Loading

0 comments on commit 553e250

Please sign in to comment.