module Strongweak.Weaken
(
Weaken(..)
, liftWeakF
, Strength(..)
, SW
) where
import Refined ( Refined, unrefine )
import Numeric.Natural ( Natural )
import Data.Word
import Data.Int
import Data.Vector.Sized qualified as Vector
import Data.Vector.Sized ( Vector )
import Data.Kind ( Type )
import Data.Functor.Identity
import Data.Functor.Const
import Data.List.NonEmpty qualified as NonEmpty
import Data.List.NonEmpty ( NonEmpty )
class Weaken a where
type Weak a :: Type
weaken :: a -> Weak a
liftWeakF :: Weaken a => (Weak a -> b) -> (a -> b)
liftWeakF :: forall a b. Weaken a => (Weak a -> b) -> a -> b
liftWeakF Weak a -> b
f = Weak a -> b
f (Weak a -> b) -> (a -> Weak a) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Weak a
forall a. Weaken a => a -> Weak a
weaken
data Strength = Strong | Weak
type family SW (s :: Strength) a :: Type where
SW 'Strong a = a
SW 'Weak a = Weak a
instance Weaken (NonEmpty a) where
type Weak (NonEmpty a) = [a]
weaken :: NonEmpty a -> Weak (NonEmpty a)
weaken = NonEmpty a -> Weak (NonEmpty a)
forall a. NonEmpty a -> [a]
NonEmpty.toList
instance Weaken (Vector n a) where
type Weak (Vector n a) = [a]
weaken :: Vector n a -> Weak (Vector n a)
weaken = Vector n a -> Weak (Vector n a)
forall (n :: Nat) a. Vector n a -> [a]
Vector.toList
instance Weaken (Refined p a) where
type Weak (Refined p a) = a
weaken :: Refined p a -> Weak (Refined p a)
weaken = Refined p a -> Weak (Refined p a)
forall p x. Refined p x -> x
unrefine
instance Weaken Word8 where
type Weak Word8 = Natural
weaken :: Word8 -> Weak Word8
weaken = Word8 -> Weak Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral
instance Weaken Word16 where
type Weak Word16 = Natural
weaken :: Word16 -> Weak Word16
weaken = Word16 -> Weak Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral
instance Weaken Word32 where
type Weak Word32 = Natural
weaken :: Word32 -> Weak Word32
weaken = Word32 -> Weak Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral
instance Weaken Word64 where
type Weak Word64 = Natural
weaken :: Word64 -> Weak Word64
weaken = Word64 -> Weak Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
instance Weaken Int8 where
type Weak Int8 = Integer
weaken :: Int8 -> Weak Int8
weaken = Int8 -> Weak Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral
instance Weaken Int16 where
type Weak Int16 = Integer
weaken :: Int16 -> Weak Int16
weaken = Int16 -> Weak Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral
instance Weaken Int32 where
type Weak Int32 = Integer
weaken :: Int32 -> Weak Int32
weaken = Int32 -> Weak Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral
instance Weaken Int64 where
type Weak Int64 = Integer
weaken :: Int64 -> Weak Int64
weaken = Int64 -> Weak Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
instance Weaken a => Weaken [a] where
type Weak [a] = [Weak a]
weaken :: [a] -> Weak [a]
weaken = (a -> Weak a) -> [a] -> [Weak a]
forall a b. (a -> b) -> [a] -> [b]
map a -> Weak a
forall a. Weaken a => a -> Weak a
weaken
instance (Weaken a, Weaken b) => Weaken (a, b) where
type Weak (a, b) = (Weak a, Weak b)
weaken :: (a, b) -> Weak (a, b)
weaken (a
a, b
b) = (a -> Weak a
forall a. Weaken a => a -> Weak a
weaken a
a, b -> Weak b
forall a. Weaken a => a -> Weak a
weaken b
b)
instance Weaken a => Weaken (Maybe a) where
type Weak (Maybe a) = Maybe (Weak a)
weaken :: Maybe a -> Weak (Maybe a)
weaken = \case Just a
a -> Weak a -> Maybe (Weak a)
forall a. a -> Maybe a
Just (Weak a -> Maybe (Weak a)) -> Weak a -> Maybe (Weak a)
forall a b. (a -> b) -> a -> b
$ a -> Weak a
forall a. Weaken a => a -> Weak a
weaken a
a
Maybe a
Nothing -> Weak (Maybe a)
forall a. Maybe a
Nothing
instance (Weaken a, Weaken b) => Weaken (Either a b) where
type Weak (Either a b) = Either (Weak a) (Weak b)
weaken :: Either a b -> Weak (Either a b)
weaken = \case Left a
a -> Weak a -> Either (Weak a) (Weak b)
forall a b. a -> Either a b
Left (Weak a -> Either (Weak a) (Weak b))
-> Weak a -> Either (Weak a) (Weak b)
forall a b. (a -> b) -> a -> b
$ a -> Weak a
forall a. Weaken a => a -> Weak a
weaken a
a
Right b
b -> Weak b -> Either (Weak a) (Weak b)
forall a b. b -> Either a b
Right (Weak b -> Either (Weak a) (Weak b))
-> Weak b -> Either (Weak a) (Weak b)
forall a b. (a -> b) -> a -> b
$ b -> Weak b
forall a. Weaken a => a -> Weak a
weaken b
b
instance Weaken a => Weaken (Identity a) where
type Weak (Identity a) = Identity (Weak a)
weaken :: Identity a -> Weak (Identity a)
weaken = Weak a -> Identity (Weak a)
forall a. a -> Identity a
Identity (Weak a -> Identity (Weak a))
-> (Identity a -> Weak a) -> Identity a -> Identity (Weak a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Weak a
forall a. Weaken a => a -> Weak a
weaken (a -> Weak a) -> (Identity a -> a) -> Identity a -> Weak a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identity a -> a
forall a. Identity a -> a
runIdentity
instance Weaken a => Weaken (Const a b) where
type Weak (Const a b) = Const (Weak a) b
weaken :: Const a b -> Weak (Const a b)
weaken = Weak a -> Const (Weak a) b
forall {k} a (b :: k). a -> Const a b
Const (Weak a -> Const (Weak a) b)
-> (Const a b -> Weak a) -> Const a b -> Const (Weak a) b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Weak a
forall a. Weaken a => a -> Weak a
weaken (a -> Weak a) -> (Const a b -> a) -> Const a b -> Weak a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Const a b -> a
forall {k} a (b :: k). Const a b -> a
getConst