{-# LANGUAGE CPP                    #-}
{-# LANGUAGE DefaultSignatures      #-}
{-# LANGUAGE FlexibleInstances      #-}
{-# LANGUAGE FunctionalDependencies #-}
module Distribution.Compat.Newtype (
    Newtype (..),
    ala,
    alaf,
    pack',
    unpack',
    ) where
import Data.Functor.Identity (Identity (..))
import Data.Monoid (Sum (..), Product (..), Endo (..))
#if MIN_VERSION_base(4,7,0)
import Data.Coerce (coerce, Coercible)
#else
import Unsafe.Coerce (unsafeCoerce)
#endif
class Newtype o n | n -> o where
    pack   :: o -> n
#if MIN_VERSION_base(4,7,0)
    default pack :: Coercible o n => o -> n
    pack = o -> n
forall a b. Coercible a b => a -> b
coerce
#else
    default pack :: o -> n
    pack = unsafeCoerce
#endif
    unpack :: n -> o
#if MIN_VERSION_base(4,7,0)
    default unpack :: Coercible n o => n -> o
    unpack = n -> o
forall a b. Coercible a b => a -> b
coerce
#else
    default unpack :: n -> o
    unpack = unsafeCoerce
#endif
instance Newtype a (Identity a)
instance Newtype a (Sum a)
instance Newtype a (Product a)
instance Newtype (a -> a) (Endo a)
ala :: (Newtype o n, Newtype o' n') => (o -> n) -> ((o -> n) -> b -> n') -> (b -> o')
ala :: forall o n o' n' b.
(Newtype o n, Newtype o' n') =>
(o -> n) -> ((o -> n) -> b -> n') -> b -> o'
ala o -> n
pa (o -> n) -> b -> n'
hof = (o -> n) -> ((o -> n) -> b -> n') -> (o -> o) -> b -> o'
forall o n o' n' a b.
(Newtype o n, Newtype o' n') =>
(o -> n) -> ((a -> n) -> b -> n') -> (a -> o) -> b -> o'
alaf o -> n
pa (o -> n) -> b -> n'
hof o -> o
forall a. a -> a
id
alaf :: (Newtype o n, Newtype o' n') => (o -> n) -> ((a -> n) -> b -> n') -> (a -> o) -> (b -> o')
alaf :: forall o n o' n' a b.
(Newtype o n, Newtype o' n') =>
(o -> n) -> ((a -> n) -> b -> n') -> (a -> o) -> b -> o'
alaf o -> n
_ (a -> n) -> b -> n'
hof a -> o
f = n' -> o'
forall o n. Newtype o n => n -> o
unpack (n' -> o') -> (b -> n') -> b -> o'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> n) -> b -> n'
hof (o -> n
forall o n. Newtype o n => o -> n
pack (o -> n) -> (a -> o) -> a -> n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> o
f)
pack' :: Newtype o n => (o -> n) -> o -> n
pack' :: forall o n. Newtype o n => (o -> n) -> o -> n
pack' o -> n
_ = o -> n
forall o n. Newtype o n => o -> n
pack
unpack' :: Newtype o n => (o -> n) -> n -> o
unpack' :: forall o n. Newtype o n => (o -> n) -> n -> o
unpack' o -> n
_ = n -> o
forall o n. Newtype o n => n -> o
unpack