|
| 1 | +module Strongweak.Chain ( SWChain(..), strengthenN ) where |
| 2 | + |
| 3 | +import Strongweak.Weaken ( Weaken(..), WeakenN(weakenN), type WeakenedN ) |
| 4 | +import Strongweak.Strengthen ( Strengthen(..), StrengthenN(strengthenN) ) |
| 5 | +import GHC.TypeNats ( type Natural ) |
| 6 | + |
| 7 | +{- | When weakening (or strengthening), chain the operation @n@ times. |
| 8 | +
|
| 9 | +You may achieve this without extra newtypes by nesting uses of |
| 10 | +'Strongweak.Strength.SW'. However, strongweak generics can't handle this, |
| 11 | +forcing you to write manual instances. |
| 12 | +
|
| 13 | +'SWChain' provides this nesting behaviour in a type. In return for adding a |
| 14 | +boring newtype layer to the strong representation, you can chain weakening and |
| 15 | +strengthenings without having to write them manually. |
| 16 | +
|
| 17 | +The type works as follows: |
| 18 | +
|
| 19 | +@ |
| 20 | +'Weakened' ('SWChain' 0 a) = a |
| 21 | +'Weakened' ('SWChain' 1 a) = 'Weakened' a |
| 22 | +'Weakened' ('SWChain' 2 a) = 'Weakened' ('Weakened' a) |
| 23 | +'Weakened' ('SWChain' n a) = 'WeakenedN' n a |
| 24 | +@ |
| 25 | +
|
| 26 | +And so on. (This type is only much use from @n = 2@ onwards.) |
| 27 | +
|
| 28 | +You may also use this as a "via" type: |
| 29 | +
|
| 30 | +@ |
| 31 | +newtype A (s :: 'Strength') = A { a1 :: 'SW' s (Identity ('SW' s Word8)) } |
| 32 | +deriving via 'SWChain' 2 (Identity Word8) instance 'Weaken' (A 'Strong') |
| 33 | +deriving via 'SWChain' 2 (Identity Word8) instance 'Strengthen' (A 'Strong') |
| 34 | +@ |
| 35 | +-} |
| 36 | +newtype SWChain (n :: Natural) a = SWChain { unSWChain :: a } |
| 37 | + deriving stock Show |
| 38 | + deriving (Ord, Eq) via a |
| 39 | + |
| 40 | +instance WeakenN n a => Weaken (SWChain n a) where |
| 41 | + type Weakened (SWChain n a) = WeakenedN n a |
| 42 | + weaken = weakenN @n . unSWChain |
| 43 | + |
| 44 | +instance StrengthenN n a => Strengthen (SWChain n a) where |
| 45 | + strengthen = fmap SWChain . strengthenN @n |
0 commit comments