Skip to content

Commit

Permalink
Strongweak.Generic: +GenericallySW0
Browse files Browse the repository at this point in the history
  • Loading branch information
raehik committed Oct 16, 2024
1 parent c114cf0 commit 6b470f9
Showing 1 changed file with 29 additions and 8 deletions.
37 changes: 29 additions & 8 deletions src/Strongweak/Generic.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ module Strongweak.Generic
weakenGeneric
, strengthenGeneric

-- * Generic wrapper
-- * Generic deriving via wrappers
, GenericallySW(..)
, GenericallySW0(..)
) where

import Strongweak.Weaken.Generic
Expand All @@ -23,6 +24,8 @@ import Strongweak.Strengthen ( Strengthen(strengthen) )
import GHC.Generics
import Data.Kind ( Type )

import Strongweak.Strength

{- $generic-derivation-compatibility
The 'Strengthen' and 'Weaken' generic derivers allow you to derive instances
Expand All @@ -47,8 +50,8 @@ bad idea) do not require it.
Note that the generics only handle one "layer" at a time. If you have a data
type with nested 'Strongweak.Strengthen.SW' uses, these generics will fail with
a type error. Write the instance manually instead. (I can't think of an easy way
to handle this, but TODO all the same.)
a type error. Either use 'Strongweak.WeakenN.WeakenN', or write the instances
manually.
-}

{- | @DerivingVia@ wrapper for strongweak instances.
Expand All @@ -70,12 +73,8 @@ deriving via (GenericallySW (XYZ 'Strong) (XYZ 'Weak)) instance Weaken (XYZ 'Str
deriving via (GenericallySW (XYZ 'Strong) (XYZ 'Weak)) instance Strengthen (XYZ 'Strong)
@
TODO can't figure out a way around multiple standalone deriving declarations :(
TODO maybe GenericallySW1? but even so instances differ between weaken and
strengthen (weaken needs nothing) so it's kinda better this way. :)
Regrettably, use of this requires UndecidableInstances.
-}

newtype GenericallySW s (w :: Type) = GenericallySW { unGenericallySW :: s }

instance
Expand All @@ -91,3 +90,25 @@ instance
, Weaken (GenericallySW s w)
) => Strengthen (GenericallySW s w) where
strengthen = fmap GenericallySW . strengthenGeneric

-- | 'GenericallySW' where the type takes a 'Strength' in its last type var.
--
-- Shorter instances for types of a certain shape.
--
-- Regrettably, use of this requires UndecidableInstances.
newtype GenericallySW0 (f :: Strength -> Type)
= GenericallySW0 { unGenericallySW0 :: f Strong }

instance
( Generic (f Strong), Generic (f Weak)
, GWeaken (Rep (f Strong)) (Rep (f Weak))
) => Weaken (GenericallySW0 f) where
type Weakened (GenericallySW0 f) = f Weak
weaken = weakenGeneric . unGenericallySW0

instance
( Generic (f Strong), Generic (f Weak)
, GStrengthenD (Rep (f Weak)) (Rep (f Strong))
, Weaken (GenericallySW0 f)
) => Strengthen (GenericallySW0 f) where
strengthen = fmap GenericallySW0 . strengthenGeneric

0 comments on commit 6b470f9

Please sign in to comment.