{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}

-- |
-- Unsafe ops inside encoding
module Data.TypedEncoding.Common.Types.Unsafe where

import           Data.Proxy
import           Data.TypedEncoding.Common.Types

 
-- | Allows to operate within @Enc@
-- keeping the same list of encodings.
--
-- These are considered unsafe. 
--
-- @since 0.1.0.0 
newtype Unsafe enc conf str = Unsafe {Unsafe @k enc conf str -> Enc @k enc conf str
runUnsafe :: Enc enc conf str} deriving (Int -> Unsafe @k enc conf str -> ShowS
[Unsafe @k enc conf str] -> ShowS
Unsafe @k enc conf str -> String
(Int -> Unsafe @k enc conf str -> ShowS)
-> (Unsafe @k enc conf str -> String)
-> ([Unsafe @k enc conf str] -> ShowS)
-> Show (Unsafe @k enc conf str)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k (enc :: k) conf str.
(Show conf, Show str) =>
Int -> Unsafe @k enc conf str -> ShowS
forall k (enc :: k) conf str.
(Show conf, Show str) =>
[Unsafe @k enc conf str] -> ShowS
forall k (enc :: k) conf str.
(Show conf, Show str) =>
Unsafe @k enc conf str -> String
showList :: [Unsafe @k enc conf str] -> ShowS
$cshowList :: forall k (enc :: k) conf str.
(Show conf, Show str) =>
[Unsafe @k enc conf str] -> ShowS
show :: Unsafe @k enc conf str -> String
$cshow :: forall k (enc :: k) conf str.
(Show conf, Show str) =>
Unsafe @k enc conf str -> String
showsPrec :: Int -> Unsafe @k enc conf str -> ShowS
$cshowsPrec :: forall k (enc :: k) conf str.
(Show conf, Show str) =>
Int -> Unsafe @k enc conf str -> ShowS
Show)

-- |
-- @since 0.1.0.
withUnsafe :: (Unsafe e c s1 -> Unsafe e c s2) -> Enc e c s1 -> Enc e c s2
withUnsafe :: (Unsafe @k e c s1 -> Unsafe @k e c s2)
-> Enc @k e c s1 -> Enc @k e c s2
withUnsafe Unsafe @k e c s1 -> Unsafe @k e c s2
f Enc @k e c s1
enc = Unsafe @k e c s2 -> Enc @k e c s2
forall k (enc :: k) conf str.
Unsafe @k enc conf str -> Enc @k enc conf str
runUnsafe (Unsafe @k e c s2 -> Enc @k e c s2)
-> (Unsafe @k e c s1 -> Unsafe @k e c s2)
-> Unsafe @k e c s1
-> Enc @k e c s2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Unsafe @k e c s1 -> Unsafe @k e c s2
f (Unsafe @k e c s1 -> Enc @k e c s2)
-> Unsafe @k e c s1 -> Enc @k e c s2
forall a b. (a -> b) -> a -> b
$ Enc @k e c s1 -> Unsafe @k e c s1
forall k (enc :: k) conf str.
Enc @k enc conf str -> Unsafe @k enc conf str
Unsafe Enc @k e c s1
enc

instance Functor (Unsafe enc conf) where
    fmap :: (a -> b) -> Unsafe @k enc conf a -> Unsafe @k enc conf b
fmap a -> b
f (Unsafe (UnsafeMkEnc Proxy @k enc
p conf
c a
x)) = Enc @k enc conf b -> Unsafe @k enc conf b
forall k (enc :: k) conf str.
Enc @k enc conf str -> Unsafe @k enc conf str
Unsafe (Proxy @k enc -> conf -> b -> Enc @k enc conf b
forall k (nms :: k) conf str.
Proxy @k nms -> conf -> str -> Enc @k nms conf str
UnsafeMkEnc Proxy @k enc
p conf
c (a -> b
f a
x))
  
instance Applicative (Unsafe enc ()) where
    pure :: a -> Unsafe @k enc () a
pure = Enc @k enc () a -> Unsafe @k enc () a
forall k (enc :: k) conf str.
Enc @k enc conf str -> Unsafe @k enc conf str
Unsafe (Enc @k enc () a -> Unsafe @k enc () a)
-> (a -> Enc @k enc () a) -> a -> Unsafe @k enc () a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy @k enc -> () -> a -> Enc @k enc () a
forall k (nms :: k) conf str.
Proxy @k nms -> conf -> str -> Enc @k nms conf str
UnsafeMkEnc Proxy @k enc
forall k (t :: k). Proxy @k t
Proxy ()  
    Unsafe (UnsafeMkEnc Proxy @k enc
p ()
c1 a -> b
f) <*> :: Unsafe @k enc () (a -> b)
-> Unsafe @k enc () a -> Unsafe @k enc () b
<*> Unsafe (UnsafeMkEnc Proxy @k enc
_ ()
c2 a
x) = Enc @k enc () b -> Unsafe @k enc () b
forall k (enc :: k) conf str.
Enc @k enc conf str -> Unsafe @k enc conf str
Unsafe (Proxy @k enc -> () -> b -> Enc @k enc () b
forall k (nms :: k) conf str.
Proxy @k nms -> conf -> str -> Enc @k nms conf str
UnsafeMkEnc Proxy @k enc
p () (a -> b
f a
x))  

instance Monad (Unsafe enc ()) where 
    Unsafe (UnsafeMkEnc Proxy @k enc
_ ()
_ a
x) >>= :: Unsafe @k enc () a
-> (a -> Unsafe @k enc () b) -> Unsafe @k enc () b
>>= a -> Unsafe @k enc () b
f = a -> Unsafe @k enc () b
f a
x