{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE LinearTypes #-}
{-# LANGUAGE QualifiedDo #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Control.Monad.Borrow.Pure.Clone (
  Clone (..),
  genericClone,
  AsCopyable (..),
  Clone1 (..),
  clone1,
  GenericClone1,
  genericLiftClone,
  genericClone1,
) where

import Control.Functor.Linear qualified as Control
import Control.Monad.Borrow.Pure.BO.Internal
import Control.Monad.Borrow.Pure.Copyable
import Control.Monad.Borrow.Pure.Utils (coerceLin)
import Data.Coerce (Coercible, coerce)
import Data.Data (Proxy)
import Data.Int
import Data.Kind (Constraint, Type)
import Data.List.NonEmpty (NonEmpty)
import Data.Word
import GHC.Exts (Multiplicity (..))
import Generics.Linear
import Numeric.Natural
import Prelude.Linear
import Unsafe.Linear qualified as Unsafe

{- | @'Clone' a@ is analogous o @'Copyable' a@, but requires cloned values
to be accessible only inside the @'BO' α@ monad.

The difference between 'Clone' and 'Copyable' is that the former allows for
cloning a shared borrow of a /mutable/ or /linear/ value, while the latter requires cloning a shared borrow of an /immutable/ value.
This is because we can leak @'Share' α a@ via 'Prelude.Linear.Movable' instance, and
hence it can outlive the original @'BO' α@ lifetime, which allows leaking mutable states inside @a@ into /unrestricted/ contexts, which destroys the soundness severly.
-}
class Clone a where
  clone :: Share α a %1 -> BO α a
  default clone :: (GenericClone a) => Share α a %1 -> BO α a
  clone = Share α a %1 -> BO α a
forall a (α :: Lifetime). GenericClone a => Share α a %1 -> BO α a
genericClone

newtype AsCopyable a = AsCopyable a
  deriving newtype ((forall (bk :: BorrowKind) (α :: Lifetime).
 Borrow bk α (AsCopyable a) %1 -> AsCopyable a)
-> Copyable (AsCopyable a)
forall a (bk :: BorrowKind) (α :: Lifetime).
Copyable a =>
Borrow bk α (AsCopyable a) %1 -> AsCopyable a
forall a.
(forall (bk :: BorrowKind) (α :: Lifetime). Borrow bk α a %1 -> a)
-> Copyable a
forall (bk :: BorrowKind) (α :: Lifetime).
Borrow bk α (AsCopyable a) %1 -> AsCopyable a
$ccopy :: forall a (bk :: BorrowKind) (α :: Lifetime).
Copyable a =>
Borrow bk α (AsCopyable a) %1 -> AsCopyable a
copy :: forall (bk :: BorrowKind) (α :: Lifetime).
Borrow bk α (AsCopyable a) %1 -> AsCopyable a
Copyable)

instance (Copyable a) => Clone (AsCopyable a) where
  clone :: forall (α :: Lifetime).
Share α (AsCopyable a) %1 -> BO α (AsCopyable a)
clone = AsCopyable a %1 -> BO α (AsCopyable a)
forall a. a %1 -> BO α a
forall (f :: * -> *) a. Applicative f => a %1 -> f a
Control.pure (AsCopyable a %1 -> BO α (AsCopyable a))
-> (Share α (AsCopyable a) %1 -> AsCopyable a)
-> Share α (AsCopyable a)
%1 -> BO α (AsCopyable a)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. Share α (AsCopyable a) %1 -> AsCopyable a
forall a (bk :: BorrowKind) (α :: Lifetime).
Copyable a =>
Borrow bk α a %1 -> a
forall (bk :: BorrowKind) (α :: Lifetime).
Borrow bk α (AsCopyable a) %1 -> AsCopyable a
copy
  {-# INLINE clone #-}

deriving via AsCopyable Int instance Clone Int

deriving via AsCopyable Int8 instance Clone Int8

deriving via AsCopyable Int16 instance Clone Int16

deriving via AsCopyable Int32 instance Clone Int32

deriving via AsCopyable Int64 instance Clone Int64

deriving via AsCopyable Word instance Clone Word

deriving via AsCopyable Word8 instance Clone Word8

deriving via AsCopyable Word16 instance Clone Word16

deriving via AsCopyable Word32 instance Clone Word32

deriving via AsCopyable Word64 instance Clone Word64

deriving via AsCopyable Char instance Clone Char

deriving via AsCopyable Bool instance Clone Bool

deriving via AsCopyable Integer instance Clone Integer

deriving via AsCopyable Natural instance Clone Natural

deriving via AsCopyable Double instance Clone Double

deriving via AsCopyable Float instance Clone Float

deriving via AsCopyable () instance Clone ()

type GenericClone a = (Generic a, GClone (Rep a))

genericClone :: (GenericClone a) => Share α a %1 -> BO α a
{-# INLINE genericClone #-}
genericClone :: forall a (α :: Lifetime). GenericClone a => Share α a %1 -> BO α a
genericClone (UnsafeAlias a
x) = Rep a (ZonkAny 0) %1 -> a
forall a p (m :: Multiplicity). Generic a => Rep a p %m -> a
forall p (m :: Multiplicity). Rep a p %m -> a
to (Rep a (ZonkAny 0) %1 -> a)
%1 -> BO α (Rep a (ZonkAny 0)) %1 -> BO α a
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.<$> Share α (Rep a (ZonkAny 0)) %1 -> BO α (Rep a (ZonkAny 0))
forall {k} (f :: k -> *) (α :: Lifetime) (x :: k).
GClone f =>
Share α (f x) %1 -> BO α (f x)
forall (α :: Lifetime) x. Share α (Rep a x) %1 -> BO α (Rep a x)
gclone (Rep a (ZonkAny 0) -> Share α (Rep a (ZonkAny 0))
forall (ak :: AliasKind) (α :: Lifetime) a. a -> Alias ak α a
UnsafeAlias (a %1 -> Rep a (ZonkAny 0)
forall a p (m :: Multiplicity). Generic a => a %m -> Rep a p
forall p (m :: Multiplicity). a %m -> Rep a p
from a
x))

type GClone :: forall {k}. (k -> Type) -> Constraint
class GClone f where
  gclone :: Share α (f x) %1 -> BO α (f x)

instance (Clone a) => GClone (K1 i a) where
  gclone :: forall (α :: Lifetime) (x :: k).
Share α (K1 i a x) %1 -> BO α (K1 i a x)
gclone = (Share α a %1 -> BO α a)
%1 -> Share α (K1 i a x) %1 -> BO α (K1 i a x)
forall a b. Coercible a b => a %1 -> b
coerceLin ((Share α a %1 -> BO α a)
 %1 -> Share α (K1 i a x) %1 -> BO α (K1 i a x))
-> (Share α a %1 -> BO α a)
%1 -> Share α (K1 i a x)
%1 -> BO α (K1 i a x)
forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ forall a (α :: Lifetime). Clone a => Share α a %1 -> BO α a
clone @a

instance (GClone f, GClone g) => GClone (f :*: g) where
  gclone :: forall (α :: Lifetime) (x :: k).
Share α ((:*:) f g x) %1 -> BO α ((:*:) f g x)
gclone (UnsafeAlias (f x
f :*: g x
g)) =
    f x -> g x -> (:*:) f g x
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
(:*:) (f x %1 -> g x %1 -> (:*:) f g x)
%1 -> BO α (f x) %1 -> BO α (g x %1 -> (:*:) f g x)
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.<$> Share α (f x) %1 -> BO α (f x)
forall {k} (f :: k -> *) (α :: Lifetime) (x :: k).
GClone f =>
Share α (f x) %1 -> BO α (f x)
forall (α :: Lifetime) (x :: k). Share α (f x) %1 -> BO α (f x)
gclone (f x -> Share α (f x)
forall (ak :: AliasKind) (α :: Lifetime) a. a -> Alias ak α a
UnsafeAlias f x
f) BO α (g x %1 -> (:*:) f g x)
%1 -> BO α (g x) %1 -> BO α ((:*:) f g x)
forall a b. BO α (a %1 -> b) %1 -> BO α a %1 -> BO α b
forall (f :: * -> *) a b.
Applicative f =>
f (a %1 -> b) %1 -> f a %1 -> f b
Control.<*> Share α (g x) %1 -> BO α (g x)
forall {k} (f :: k -> *) (α :: Lifetime) (x :: k).
GClone f =>
Share α (f x) %1 -> BO α (f x)
forall (α :: Lifetime) (x :: k). Share α (g x) %1 -> BO α (g x)
gclone (g x -> Share α (g x)
forall (ak :: AliasKind) (α :: Lifetime) a. a -> Alias ak α a
UnsafeAlias g x
g)

instance (GClone f) => GClone (M1 i c f) where
  gclone :: forall (α :: Lifetime) (x :: k).
Share α (M1 i c f x) %1 -> BO α (M1 i c f x)
gclone = \case
    UnsafeAlias (M1 f x
x) -> BO α (f x) %1 -> BO α (M1 i c f x)
forall a b. Coercible a b => a %1 -> b
coerceLin (BO α (f x) %1 -> BO α (M1 i c f x))
-> BO α (f x) %1 -> BO α (M1 i c f x)
forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ Share α (f x) %1 -> BO α (f x)
forall {k} (f :: k -> *) (α :: Lifetime) (x :: k).
GClone f =>
Share α (f x) %1 -> BO α (f x)
forall (α :: Lifetime) (x :: k). Share α (f x) %1 -> BO α (f x)
gclone (f x -> Share α (f x)
forall (ak :: AliasKind) (α :: Lifetime) a. a -> Alias ak α a
UnsafeAlias f x
x)

instance (GClone f) => GClone (MP1 'One f) where
  gclone :: forall (α :: Lifetime) (x :: k).
Share α (MP1 'One f x) %1 -> BO α (MP1 'One f x)
gclone = \case
    UnsafeAlias (MP1 f x
x) -> f x %1 -> MP1 'One f x
forall {k} (b :: k -> *) (c :: k) (a :: Multiplicity).
b c %a -> MP1 a b c
MP1 (f x %1 -> MP1 'One f x) %1 -> BO α (f x) %1 -> BO α (MP1 'One f x)
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.<$> Share α (f x) %1 -> BO α (f x)
forall {k} (f :: k -> *) (α :: Lifetime) (x :: k).
GClone f =>
Share α (f x) %1 -> BO α (f x)
forall (α :: Lifetime) (x :: k). Share α (f x) %1 -> BO α (f x)
gclone (f x -> Share α (f x)
forall (ak :: AliasKind) (α :: Lifetime) a. a -> Alias ak α a
UnsafeAlias f x
x)

instance GClone (MP1 'Many f) where
  gclone :: forall (α :: Lifetime) (x :: k).
Share α (MP1 'Many f x) %1 -> BO α (MP1 'Many f x)
gclone = \case
    UnsafeAlias MP1 'Many f x
mp1 -> MP1 'Many f x %1 -> BO α (MP1 'Many f x)
forall a. a %1 -> BO α a
forall (f :: * -> *) a. Applicative f => a %1 -> f a
Control.pure MP1 'Many f x
mp1

instance (GClone f, GClone g) => GClone (f :+: g) where
  gclone :: forall (α :: Lifetime) (x :: k).
Share α ((:+:) f g x) %1 -> BO α ((:+:) f g x)
gclone = \case
    UnsafeAlias (L1 f x
x) -> f x -> (:+:) f g x
forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 (f x %1 -> (:+:) f g x) %1 -> BO α (f x) %1 -> BO α ((:+:) f g x)
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.<$> Share α (f x) %1 -> BO α (f x)
forall {k} (f :: k -> *) (α :: Lifetime) (x :: k).
GClone f =>
Share α (f x) %1 -> BO α (f x)
forall (α :: Lifetime) (x :: k). Share α (f x) %1 -> BO α (f x)
gclone (f x -> Share α (f x)
forall (ak :: AliasKind) (α :: Lifetime) a. a -> Alias ak α a
UnsafeAlias f x
x)
    UnsafeAlias (R1 g x
x) -> g x -> (:+:) f g x
forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 (g x %1 -> (:+:) f g x) %1 -> BO α (g x) %1 -> BO α ((:+:) f g x)
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.<$> Share α (g x) %1 -> BO α (g x)
forall {k} (f :: k -> *) (α :: Lifetime) (x :: k).
GClone f =>
Share α (f x) %1 -> BO α (f x)
forall (α :: Lifetime) (x :: k). Share α (g x) %1 -> BO α (g x)
gclone (g x -> Share α (g x)
forall (ak :: AliasKind) (α :: Lifetime) a. a -> Alias ak α a
UnsafeAlias g x
x)

instance GClone U1 where
  gclone :: forall (α :: Lifetime) (x :: k). Share α (U1 x) %1 -> BO α (U1 x)
gclone = U1 x %1 -> BO α (U1 x)
forall a. a %1 -> BO α a
forall (f :: * -> *) a. Applicative f => a %1 -> f a
Control.pure (U1 x %1 -> BO α (U1 x))
-> (Share α (U1 x) %1 -> U1 x) -> Share α (U1 x) %1 -> BO α (U1 x)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. U1 x %1 -> U1 x
forall a b. Coercible a b => a %1 -> b
coerceLin (U1 x %1 -> U1 x)
-> (Share α (U1 x) %1 -> U1 x) -> Share α (U1 x) %1 -> U1 x
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. Share α (U1 x) %1 -> U1 x
forall (ak :: AliasKind) (α :: Lifetime) a. Alias ak α a %1 -> a
unsafeUnalias

instance GClone V1 where
  gclone :: forall (α :: Lifetime) (x :: k). Share α (V1 x) %1 -> BO α (V1 x)
gclone = \case {} (V1 x %1 -> BO α (V1 x))
-> (Share α (V1 x) %1 -> V1 x) -> Share α (V1 x) %1 -> BO α (V1 x)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. Share α (V1 x) %1 -> V1 x
forall (ak :: AliasKind) (α :: Lifetime) a. Alias ak α a %1 -> a
unsafeUnalias

instance (GenericClone a) => Clone (Generically a) where
  clone :: forall (α :: Lifetime).
Share α (Generically a) %1 -> BO α (Generically a)
clone = (a %1 -> Generically a) %1 -> BO α a %1 -> BO α (Generically a)
forall a b. (a %1 -> b) %1 -> BO α a %1 -> BO α b
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap a -> Generically a
forall a. a -> Generically a
Generically (BO α a %1 -> BO α (Generically a))
-> (Share α (Generically a) %1 -> BO α a)
-> Share α (Generically a)
%1 -> BO α (Generically a)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. Share α a %1 -> BO α a
forall a (α :: Lifetime). GenericClone a => Share α a %1 -> BO α a
genericClone (Share α a %1 -> BO α a)
-> (Share α (Generically a) %1 -> Share α a)
-> Share α (Generically a)
%1 -> BO α a
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. (Generically a %1 -> a)
%1 -> Share α (Generically a) %1 -> Share α a
forall a b (ak :: AliasKind) (α :: Lifetime).
(a %1 -> b) %1 -> Alias ak α a %1 -> Alias ak α b
unsafeMapAlias (\(Generically a
x) -> a
x)

deriving via
  Generically (a, b)
  instance
    (Clone a, Clone b) => Clone (a, b)

deriving via
  Generically (a, b, c)
  instance
    (Clone a, Clone b, Clone c) => Clone (a, b, c)

deriving via
  Generically (a, b, c, d)
  instance
    (Clone a, Clone b, Clone c, Clone d) => Clone (a, b, c, d)

deriving via
  Generically (a, b, c, d, e)
  instance
    (Clone a, Clone b, Clone c, Clone d, Clone e) => Clone (a, b, c, d, e)

deriving via
  Generically (Either a b)
  instance
    (Clone a, Clone b) => Clone (Either a b)

deriving via Generically [a] instance (Clone a) => Clone [a]

deriving via Generically (Maybe a) instance (Clone a) => Clone (Maybe a)

deriving via Generically (NonEmpty a) instance (Clone a) => Clone (NonEmpty a)

-- | Lifting of the 'Clone' operation to unary type constructors.
class Clone1 f where
  liftClone :: (Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
  default liftClone :: (GenericClone1 f) => (Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
  liftClone = (Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
forall (f :: * -> *) a b (α :: Lifetime).
GenericClone1 f =>
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
genericLiftClone

clone1 :: (Clone1 f, Clone a) => Share α (f a) %1 -> BO α (f a)
{-# INLINE clone1 #-}
clone1 :: forall (f :: * -> *) a (α :: Lifetime).
(Clone1 f, Clone a) =>
Share α (f a) %1 -> BO α (f a)
clone1 = (Share α a %1 -> BO α a) -> Share α (f a) %1 -> BO α (f a)
forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
forall (f :: * -> *) (α :: Lifetime) a b.
Clone1 f =>
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
liftClone Share α a %1 -> BO α a
forall a (α :: Lifetime). Clone a => Share α a %1 -> BO α a
forall (α :: Lifetime). Share α a %1 -> BO α a
clone

type GenericClone1 f = (Clone1 (Rep1 @Type f), Generic1 f)

genericLiftClone :: forall f a b α. (GenericClone1 f) => (Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
{-# INLINE genericLiftClone #-}
genericLiftClone :: forall (f :: * -> *) a b (α :: Lifetime).
GenericClone1 f =>
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
genericLiftClone Share α a %1 -> BO α b
f (UnsafeAlias f a
x) =
  Rep1 f b %1 -> f b
forall p (m :: Multiplicity). Rep1 f p %m -> f p
forall {k} (f :: k -> *) (p :: k) (m :: Multiplicity).
Generic1 f =>
Rep1 f p %m -> f p
to1 (Rep1 f b %1 -> f b) %1 -> BO α (Rep1 f b) %1 -> BO α (f b)
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.<$> (Share α a %1 -> BO α b)
-> Share α (Rep1 f a) %1 -> BO α (Rep1 f b)
forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b)
-> Share α (Rep1 f a) %1 -> BO α (Rep1 f b)
forall (f :: * -> *) (α :: Lifetime) a b.
Clone1 f =>
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
liftClone Share α a %1 -> BO α b
f (Rep1 f a -> Share α (Rep1 f a)
forall (ak :: AliasKind) (α :: Lifetime) a. a -> Alias ak α a
UnsafeAlias (Rep1 f a %1 -> Share α (Rep1 f a))
-> Rep1 f a %1 -> Share α (Rep1 f a)
forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ f a %1 -> Rep1 f a
forall p (m :: Multiplicity). f p %m -> Rep1 f p
forall {k} (f :: k -> *) (p :: k) (m :: Multiplicity).
Generic1 f =>
f p %m -> Rep1 f p
from1 f a
x)

genericClone1 :: forall f a α. (GenericClone1 f, Clone a) => Share α (f a) %1 -> BO α (f a)
{-# INLINE genericClone1 #-}
genericClone1 :: forall (f :: * -> *) a (α :: Lifetime).
(GenericClone1 f, Clone a) =>
Share α (f a) %1 -> BO α (f a)
genericClone1 = (Share α a %1 -> BO α a) -> Share α (f a) %1 -> BO α (f a)
forall (f :: * -> *) a b (α :: Lifetime).
GenericClone1 f =>
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
genericLiftClone Share α a %1 -> BO α a
forall a (α :: Lifetime). Clone a => Share α a %1 -> BO α a
forall (α :: Lifetime). Share α a %1 -> BO α a
clone

instance (GenericClone1 f) => Clone1 (Generically1 @Type f) where
  liftClone :: forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b)
-> Share α (Generically1 f a) %1 -> BO α (Generically1 f b)
liftClone Share α a %1 -> BO α b
f = (f b %1 -> Generically1 f b)
%1 -> BO α (f b) %1 -> BO α (Generically1 f b)
forall a b. (a %1 -> b) %1 -> BO α a %1 -> BO α b
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap f b -> Generically1 f b
forall {k} (f :: k -> *) (a :: k). f a -> Generically1 f a
Generically1 (BO α (f b) %1 -> BO α (Generically1 f b))
-> (Share α (Generically1 f a) %1 -> BO α (f b))
-> Share α (Generically1 f a)
%1 -> BO α (Generically1 f b)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. (Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
forall (f :: * -> *) a b (α :: Lifetime).
GenericClone1 f =>
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
genericLiftClone Share α a %1 -> BO α b
f (Share α (f a) %1 -> BO α (f b))
-> (Share α (Generically1 f a) %1 -> Share α (f a))
-> Share α (Generically1 f a)
%1 -> BO α (f b)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. Share α (Generically1 f a) %1 -> Share α (f a)
forall a b (α :: Lifetime).
Coercible a b =>
Share α a %1 -> Share α b
coerceShr
  {-# INLINE liftClone #-}

instance (Clone a) => Clone1 (K1 i a) where
  liftClone :: forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b)
-> Share α (K1 i a a) %1 -> BO α (K1 i a b)
liftClone Share α a %1 -> BO α b
_ = (Share α a %1 -> BO α a)
-> Share α (K1 i a a) %1 -> BO α (K1 i a b)
forall a b. Coercible a b => a -> b
coerce ((Share α a %1 -> BO α a)
 -> Share α (K1 i a a) %1 -> BO α (K1 i a b))
-> (Share α a %1 -> BO α a)
-> Share α (K1 i a a)
%1 -> BO α (K1 i a b)
forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$! forall a (α :: Lifetime). Clone a => Share α a %1 -> BO α a
clone @a
  {-# INLINE liftClone #-}

instance Clone1 Par1 where
  liftClone :: forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b) -> Share α (Par1 a) %1 -> BO α (Par1 b)
liftClone Share α a %1 -> BO α b
f = BO α b %1 -> BO α (Par1 b)
forall a b. Coercible a b => a %1 -> b
coerceLin (BO α b %1 -> BO α (Par1 b))
-> (Share α (Par1 a) %1 -> BO α b)
-> Share α (Par1 a)
%1 -> BO α (Par1 b)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. Share α a %1 -> BO α b
f (Share α a %1 -> BO α b)
-> (Share α (Par1 a) %1 -> Share α a)
-> Share α (Par1 a)
%1 -> BO α b
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. Share α (Par1 a) %1 -> Share α a
forall a b (α :: Lifetime).
Coercible a b =>
Share α a %1 -> Share α b
coerceShr
  {-# INLINE liftClone #-}

instance (Clone1 f) => Clone1 (M1 i c f) where
  liftClone :: forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b)
-> Share α (M1 i c f a) %1 -> BO α (M1 i c f b)
liftClone Share α a %1 -> BO α b
f = (f b %1 -> M1 i c f b) %1 -> BO α (f b) %1 -> BO α (M1 i c f b)
forall a b. (a %1 -> b) %1 -> BO α a %1 -> BO α b
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap f b -> M1 i c f b
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (BO α (f b) %1 -> BO α (M1 i c f b))
-> (Share α (M1 i c f a) %1 -> BO α (f b))
-> Share α (M1 i c f a)
%1 -> BO α (M1 i c f b)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. (Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
forall (f :: * -> *) (α :: Lifetime) a b.
Clone1 f =>
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
liftClone Share α a %1 -> BO α b
f (Share α (f a) %1 -> BO α (f b))
-> (Share α (M1 i c f a) %1 -> Share α (f a))
-> Share α (M1 i c f a)
%1 -> BO α (f b)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. forall a b (α :: Lifetime).
Coercible a b =>
Share α a %1 -> Share α b
coerceShr @_
  {-# INLINE liftClone #-}

instance (Clone1 f, Clone1 g) => Clone1 (f :*: g) where
  liftClone :: forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b)
-> Share α ((:*:) f g a) %1 -> BO α ((:*:) f g b)
liftClone Share α a %1 -> BO α b
f (UnsafeAlias (f a
f' :*: g a
g')) =
    f b -> g b -> (:*:) f g b
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
(:*:)
      (f b %1 -> g b %1 -> (:*:) f g b)
%1 -> BO α (f b) %1 -> BO α (g b %1 -> (:*:) f g b)
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.<$> (Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
forall (f :: * -> *) (α :: Lifetime) a b.
Clone1 f =>
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
liftClone Share α a %1 -> BO α b
f (f a -> Share α (f a)
forall (ak :: AliasKind) (α :: Lifetime) a. a -> Alias ak α a
UnsafeAlias f a
f')
      BO α (g b %1 -> (:*:) f g b)
%1 -> BO α (g b) %1 -> BO α ((:*:) f g b)
forall a b. BO α (a %1 -> b) %1 -> BO α a %1 -> BO α b
forall (f :: * -> *) a b.
Applicative f =>
f (a %1 -> b) %1 -> f a %1 -> f b
Control.<*> (Share α a %1 -> BO α b) -> Share α (g a) %1 -> BO α (g b)
forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b) -> Share α (g a) %1 -> BO α (g b)
forall (f :: * -> *) (α :: Lifetime) a b.
Clone1 f =>
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
liftClone Share α a %1 -> BO α b
f (g a -> Share α (g a)
forall (ak :: AliasKind) (α :: Lifetime) a. a -> Alias ak α a
UnsafeAlias g a
g')

instance (Clone1 f, Clone1 g) => Clone1 (f :+: g) where
  liftClone :: forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b)
-> Share α ((:+:) f g a) %1 -> BO α ((:+:) f g b)
liftClone Share α a %1 -> BO α b
f = \case
    UnsafeAlias (L1 f a
x) -> (f b %1 -> (:+:) f g b) %1 -> BO α (f b) %1 -> BO α ((:+:) f g b)
forall a b. (a %1 -> b) %1 -> BO α a %1 -> BO α b
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap f b -> (:+:) f g b
forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 (BO α (f b) %1 -> BO α ((:+:) f g b))
-> (Share α (f a) %1 -> BO α (f b))
-> Share α (f a)
%1 -> BO α ((:+:) f g b)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. (Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
forall (f :: * -> *) (α :: Lifetime) a b.
Clone1 f =>
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
liftClone Share α a %1 -> BO α b
f (Share α (f a) %1 -> BO α (f b))
-> (Share α (f a) %1 -> Share α (f a))
-> Share α (f a)
%1 -> BO α (f b)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. Share α (f a) %1 -> Share α (f a)
forall a b (α :: Lifetime).
Coercible a b =>
Share α a %1 -> Share α b
coerceShr (Share α (f a) %1 -> BO α ((:+:) f g b))
-> Share α (f a) %1 -> BO α ((:+:) f g b)
forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ f a -> Share α (f a)
forall (ak :: AliasKind) (α :: Lifetime) a. a -> Alias ak α a
UnsafeAlias f a
x
    UnsafeAlias (R1 g a
x) -> (g b %1 -> (:+:) f g b) %1 -> BO α (g b) %1 -> BO α ((:+:) f g b)
forall a b. (a %1 -> b) %1 -> BO α a %1 -> BO α b
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap g b -> (:+:) f g b
forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 (BO α (g b) %1 -> BO α ((:+:) f g b))
-> (Share α (g a) %1 -> BO α (g b))
-> Share α (g a)
%1 -> BO α ((:+:) f g b)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. (Share α a %1 -> BO α b) -> Share α (g a) %1 -> BO α (g b)
forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b) -> Share α (g a) %1 -> BO α (g b)
forall (f :: * -> *) (α :: Lifetime) a b.
Clone1 f =>
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
liftClone Share α a %1 -> BO α b
f (Share α (g a) %1 -> BO α (g b))
-> (Share α (g a) %1 -> Share α (g a))
-> Share α (g a)
%1 -> BO α (g b)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. Share α (g a) %1 -> Share α (g a)
forall a b (α :: Lifetime).
Coercible a b =>
Share α a %1 -> Share α b
coerceShr (Share α (g a) %1 -> BO α ((:+:) f g b))
-> Share α (g a) %1 -> BO α ((:+:) f g b)
forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ g a -> Share α (g a)
forall (ak :: AliasKind) (α :: Lifetime) a. a -> Alias ak α a
UnsafeAlias g a
x
  {-# INLINE liftClone #-}

instance (Clone1 f, Clone1 g) => Clone1 (f :.: g) where
  liftClone :: forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b)
-> Share α ((:.:) f g a) %1 -> BO α ((:.:) f g b)
liftClone Share α a %1 -> BO α b
f = \(UnsafeAlias (Comp1 f (g a)
x)) -> (f (g b) %1 -> (:.:) f g b)
%1 -> BO α (f (g b)) %1 -> BO α ((:.:) f g b)
forall a b. (a %1 -> b) %1 -> BO α a %1 -> BO α b
forall (f :: * -> *) a b.
Functor f =>
(a %1 -> b) %1 -> f a %1 -> f b
Control.fmap f (g b) -> (:.:) f g b
forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (x :: k1).
f (g x) -> (:.:) f g x
Comp1 (BO α (f (g b)) %1 -> BO α ((:.:) f g b))
-> (Share α (f (g a)) %1 -> BO α (f (g b)))
-> Share α (f (g a))
%1 -> BO α ((:.:) f g b)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. (Share α (g a) %1 -> BO α (g b))
-> Share α (f (g a)) %1 -> BO α (f (g b))
forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
forall (f :: * -> *) (α :: Lifetime) a b.
Clone1 f =>
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
liftClone ((Share α a %1 -> BO α b) -> Share α (g a) %1 -> BO α (g b)
forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b) -> Share α (g a) %1 -> BO α (g b)
forall (f :: * -> *) (α :: Lifetime) a b.
Clone1 f =>
(Share α a %1 -> BO α b) -> Share α (f a) %1 -> BO α (f b)
liftClone Share α a %1 -> BO α b
f) (Share α (f (g a)) %1 -> BO α ((:.:) f g b))
-> Share α (f (g a)) %1 -> BO α ((:.:) f g b)
forall a b (p :: Multiplicity) (q :: Multiplicity).
(a %p -> b) %q -> a %p -> b
$ f (g a) -> Share α (f (g a))
forall (ak :: AliasKind) (α :: Lifetime) a. a -> Alias ak α a
UnsafeAlias f (g a)
x
  {-# INLINE liftClone #-}

instance Clone1 U1 where
  liftClone :: forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b) -> Share α (U1 a) %1 -> BO α (U1 b)
liftClone Share α a %1 -> BO α b
_ = BO α (U1 a) %1 -> BO α (U1 b)
forall a b. Coercible a b => a %1 -> b
coerceLin (BO α (U1 a) %1 -> BO α (U1 b))
-> (Share α (U1 a) %1 -> BO α (U1 a))
-> Share α (U1 a)
%1 -> BO α (U1 b)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. Share α (U1 a) %1 -> BO α (U1 a)
forall {k} (f :: k -> *) (α :: Lifetime) (x :: k).
GClone f =>
Share α (f x) %1 -> BO α (f x)
forall (α :: Lifetime) x. Share α (U1 x) %1 -> BO α (U1 x)
gclone
  {-# INLINE liftClone #-}

instance Clone1 V1 where
  liftClone :: forall (α :: Lifetime) a b.
(Share α a %1 -> BO α b) -> Share α (V1 a) %1 -> BO α (V1 b)
liftClone Share α a %1 -> BO α b
_ = \case {} (V1 a %1 -> BO α (V1 b))
-> (Share α (V1 a) %1 -> V1 a) -> Share α (V1 a) %1 -> BO α (V1 b)
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. Share α (V1 a) %1 -> V1 a
forall (ak :: AliasKind) (α :: Lifetime) a. Alias ak α a %1 -> a
unsafeUnalias
  {-# INLINE liftClone #-}

coerceShr :: (Coercible a b) => Share α a %1 -> Share α b
coerceShr :: forall a b (α :: Lifetime).
Coercible a b =>
Share α a %1 -> Share α b
coerceShr = (Share α a -> Share α b) %1 -> Share α a %1 -> Share α b
forall a b (p :: Multiplicity) (x :: Multiplicity).
(a %p -> b) %1 -> a %x -> b
Unsafe.toLinear \ !Share α a
a -> Share α a -> Share α b
forall a b. Coercible a b => a -> b
coerce Share α a
a

deriving via Generically1 Maybe instance Clone1 Maybe

deriving via Generically1 [] instance Clone1 []

deriving via Generically1 Proxy instance Clone1 Proxy

deriving via Generically1 NonEmpty instance Clone1 NonEmpty

deriving via Generically1 (Either a) instance (Clone a) => Clone1 (Either a)

deriving via Generically1 ((,) a) instance (Clone a) => Clone1 ((,) a)