{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE UndecidableInstances #-}
module Language.Jsonnet.Value where
import Control.Applicative
import Control.Arrow
import Control.Monad.Except
import Control.Monad.IO.Class
import Control.Monad.Reader
import Control.Monad.State.Lazy
import Data.Bits
import Data.ByteString (ByteString)
import Data.Data
import Data.HashMap.Lazy (HashMap)
import qualified Data.HashMap.Lazy as H
import Data.Hashable (Hashable)
import Data.IORef
import Data.Int
import Data.Map.Lazy (Map)
import qualified Data.Map.Lazy as M
import Data.Scientific (Scientific, fromFloatDigits, toRealFloat)
import Data.Text (Text)
import qualified Data.Text as T
import Data.Text.Encoding (decodeUtf8, encodeUtf8)
import Data.Typeable
import Data.Vector (Vector, (!?))
import qualified Data.Vector as V
import Debug.Trace
import GHC.Generics (Generic)
import Language.Jsonnet.Common
import Language.Jsonnet.Core
import Language.Jsonnet.Error
import {-# SOURCE #-} Language.Jsonnet.Eval (eval, evalClos)
import Language.Jsonnet.Eval.Monad
import Language.Jsonnet.Parser.SrcSpan
import Language.Jsonnet.Pretty ()
import Text.PrettyPrint.ANSI.Leijen (Doc, pretty)
import Unbound.Generics.LocallyNameless
data Value
= VNull
| VBool !Bool
| VNum !Scientific
| VStr !Text
| VArr !Array
| VObj !(HashMap Text (Hideable Thunk))
| VClos !Fun !Env
| VFun !(Thunk -> Eval Value)
deriving ((forall x. Value -> Rep Value x)
-> (forall x. Rep Value x -> Value) -> Generic Value
forall x. Rep Value x -> Value
forall x. Value -> Rep Value x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Value x -> Value
$cfrom :: forall x. Value -> Rep Value x
Generic)
type Array = Vector Thunk
type Object = HashMap Text (Hideable Thunk)
valueType :: Value -> Text
valueType :: Value -> Text
valueType =
\case
Value
VNull -> Text
"null"
VBool Bool
_ -> Text
"boolean"
VNum Scientific
_ -> Text
"number"
VStr Text
_ -> Text
"string"
VArr Array
_ -> Text
"array"
VObj HashMap Text (Hideable Thunk)
_ -> Text
"object"
VClos Fun
_ Env
_ -> Text
"function"
VFun Thunk -> Eval Value
_ -> Text
"function"
data Thunk = TC !Ctx !Core | TV !(Eval Value)
deriving ((forall x. Thunk -> Rep Thunk x)
-> (forall x. Rep Thunk x -> Thunk) -> Generic Thunk
forall x. Rep Thunk x -> Thunk
forall x. Thunk -> Rep Thunk x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Thunk x -> Thunk
$cfrom :: forall x. Thunk -> Rep Thunk x
Generic)
force :: Thunk -> Eval Value
force :: Thunk -> Eval Value
force = \case
TC Ctx
rho Core
expr -> Ctx -> Eval Value -> Eval Value
forall a. Ctx -> Eval a -> Eval a
withCtx Ctx
rho (Core -> Eval Value
eval Core
expr)
TV Eval Value
comp -> Eval Value
comp
mkThunk' :: Value -> Thunk
mkThunk' :: Value -> Thunk
mkThunk' = Eval Value -> Thunk
TV (Eval Value -> Thunk) -> (Value -> Eval Value) -> Value -> Thunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Eval Value
forall (f :: * -> *) a. Applicative f => a -> f a
pure
mkThunk :: MonadIO m => Eval Value -> m Thunk
mkThunk :: forall (m :: * -> *). MonadIO m => Eval Value -> m Thunk
mkThunk Eval Value
ev = do
IORef (Maybe Value)
ref <- IO (IORef (Maybe Value)) -> m (IORef (Maybe Value))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (Maybe Value)) -> m (IORef (Maybe Value)))
-> IO (IORef (Maybe Value)) -> m (IORef (Maybe Value))
forall a b. (a -> b) -> a -> b
$ Maybe Value -> IO (IORef (Maybe Value))
forall a. a -> IO (IORef a)
newIORef Maybe Value
forall a. Maybe a
Nothing
Thunk -> m Thunk
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Thunk -> m Thunk) -> Thunk -> m Thunk
forall a b. (a -> b) -> a -> b
$
Eval Value -> Thunk
TV (Eval Value -> Thunk) -> Eval Value -> Thunk
forall a b. (a -> b) -> a -> b
$
IO (Maybe Value) -> Eval (Maybe Value)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IORef (Maybe Value) -> IO (Maybe Value)
forall a. IORef a -> IO a
readIORef IORef (Maybe Value)
ref) Eval (Maybe Value) -> (Maybe Value -> Eval Value) -> Eval Value
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe Value
Nothing -> do
Value
v <- Eval Value
ev
IO () -> Eval ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Eval ()) -> IO () -> Eval ()
forall a b. (a -> b) -> a -> b
$ IORef (Maybe Value) -> Maybe Value -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Maybe Value)
ref (Maybe Value -> IO ()) -> Maybe Value -> IO ()
forall a b. (a -> b) -> a -> b
$ Value -> Maybe Value
forall a. a -> Maybe a
Just Value
v
Value -> Eval Value
forall (f :: * -> *) a. Applicative f => a -> f a
pure Value
v
Just Value
v -> Value -> Eval Value
forall (f :: * -> *) a. Applicative f => a -> f a
pure Value
v
proj' :: HasValue a => Thunk -> Eval a
proj' :: forall a. HasValue a => Thunk -> Eval a
proj' = Thunk -> Eval Value
force (Thunk -> Eval Value) -> (Value -> Eval a) -> Thunk -> Eval a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Value -> Eval a
forall a. HasValue a => Value -> Eval a
proj
class HasValue a where
proj :: Value -> Eval a
inj :: a -> Value
instance {-# OVERLAPS #-} HasValue Value where
proj :: Value -> Eval Value
proj = Value -> Eval Value
forall (f :: * -> *) a. Applicative f => a -> f a
pure
inj :: Value -> Value
inj = Value -> Value
forall a. a -> a
id
instance HasValue Bool where
proj :: Value -> Eval Bool
proj (VBool Bool
n) = Bool -> Eval Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
n
proj Value
v = Text -> Value -> Eval Bool
forall a. Text -> Value -> Eval a
throwTypeMismatch Text
"bool" Value
v
inj :: Bool -> Value
inj = Bool -> Value
VBool
instance HasValue Text where
proj :: Value -> Eval Text
proj (VStr Text
s) = Text -> Eval Text
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
s
proj Value
v = Text -> Value -> Eval Text
forall a. Text -> Value -> Eval a
throwTypeMismatch Text
"string" Value
v
inj :: Text -> Value
inj = Text -> Value
VStr
instance {-# OVERLAPPING #-} HasValue [Char] where
proj :: Value -> Eval [Char]
proj (VStr Text
s) = [Char] -> Eval [Char]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char] -> Eval [Char]) -> [Char] -> Eval [Char]
forall a b. (a -> b) -> a -> b
$ Text -> [Char]
T.unpack Text
s
proj Value
v = Text -> Value -> Eval [Char]
forall a. Text -> Value -> Eval a
throwTypeMismatch Text
"string" Value
v
inj :: [Char] -> Value
inj = Text -> Value
VStr (Text -> Value) -> ([Char] -> Text) -> [Char] -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Text
T.pack
instance HasValue ByteString where
proj :: Value -> Eval ByteString
proj (VStr Text
s) = ByteString -> Eval ByteString
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> ByteString
encodeUtf8 Text
s)
proj Value
v = Text -> Value -> Eval ByteString
forall a. Text -> Value -> Eval a
throwTypeMismatch Text
"string" Value
v
inj :: ByteString -> Value
inj = Text -> Value
VStr (Text -> Value) -> (ByteString -> Text) -> ByteString -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
decodeUtf8
instance HasValue Scientific where
proj :: Value -> Eval Scientific
proj (VNum Scientific
n) = Scientific -> Eval Scientific
forall (f :: * -> *) a. Applicative f => a -> f a
pure Scientific
n
proj Value
v = Text -> Value -> Eval Scientific
forall a. Text -> Value -> Eval a
throwTypeMismatch Text
"number" Value
v
inj :: Scientific -> Value
inj = Scientific -> Value
VNum
instance HasValue Double where
proj :: Value -> Eval Double
proj (VNum Scientific
n) = Double -> Eval Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Scientific -> Double
forall a. RealFloat a => Scientific -> a
toRealFloat Scientific
n)
proj Value
v = Text -> Value -> Eval Double
forall a. Text -> Value -> Eval a
throwTypeMismatch Text
"number" Value
v
inj :: Double -> Value
inj = Scientific -> Value
VNum (Scientific -> Value) -> (Double -> Scientific) -> Double -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Scientific
forall a. RealFloat a => a -> Scientific
fromFloatDigits
instance {-# OVERLAPS #-} Integral a => HasValue a where
proj :: Value -> Eval a
proj (VNum Scientific
n) = a -> Eval a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Scientific -> a
forall a b. (RealFrac a, Integral b) => a -> b
round Scientific
n)
proj Value
v = Text -> Value -> Eval a
forall a. Text -> Value -> Eval a
throwTypeMismatch Text
"number" Value
v
inj :: a -> Value
inj = Scientific -> Value
VNum (Scientific -> Value) -> (a -> Scientific) -> a -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Scientific
forall a b. (Integral a, Num b) => a -> b
fromIntegral
instance HasValue a => HasValue (Maybe a) where
proj :: Value -> Eval (Maybe a)
proj Value
VNull = Maybe a -> Eval (Maybe a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing
proj Value
a = a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> Eval a -> Eval (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Eval a
forall a. HasValue a => Value -> Eval a
proj Value
a
inj :: Maybe a -> Value
inj Maybe a
Nothing = Value
VNull
inj (Just a
a) = a -> Value
forall a. HasValue a => a -> Value
inj a
a
instance HasValue a => HasValue (Vector a) where
proj :: Value -> Eval (Vector a)
proj (VArr Array
as) = (Thunk -> Eval a) -> Array -> Eval (Vector a)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Thunk -> Eval a
forall a. HasValue a => Thunk -> Eval a
proj' Array
as
proj Value
v = Text -> Value -> Eval (Vector a)
forall a. Text -> Value -> Eval a
throwTypeMismatch Text
"array" Value
v
inj :: Vector a -> Value
inj Vector a
as = Array -> Value
VArr (Array -> Value) -> Array -> Value
forall a b. (a -> b) -> a -> b
$ Value -> Thunk
mkThunk' (Value -> Thunk) -> (a -> Value) -> a -> Thunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Value
forall a. HasValue a => a -> Value
inj (a -> Thunk) -> Vector a -> Array
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector a
as
instance {-# OVERLAPS #-} HasValue (Vector Thunk) where
proj :: Value -> Eval Array
proj (VArr Array
as) = Array -> Eval Array
forall (f :: * -> *) a. Applicative f => a -> f a
pure Array
as
proj Value
v = Text -> Value -> Eval Array
forall a. Text -> Value -> Eval a
throwTypeMismatch Text
"array" Value
v
inj :: Array -> Value
inj = Array -> Value
VArr
instance {-# OVERLAPPABLE #-} HasValue a => HasValue [a] where
proj :: Value -> Eval [a]
proj = (Vector a -> [a]) -> Eval (Vector a) -> Eval [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector a -> [a]
forall a. Vector a -> [a]
V.toList (Eval (Vector a) -> Eval [a])
-> (Value -> Eval (Vector a)) -> Value -> Eval [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Eval (Vector a)
forall a. HasValue a => Value -> Eval a
proj
inj :: [a] -> Value
inj = Vector a -> Value
forall a. HasValue a => a -> Value
inj (Vector a -> Value) -> ([a] -> Vector a) -> [a] -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Vector a
forall a. [a] -> Vector a
V.fromList
instance {-# OVERLAPS #-} HasValue Object where
proj :: Value -> Eval (HashMap Text (Hideable Thunk))
proj (VObj HashMap Text (Hideable Thunk)
o) = HashMap Text (Hideable Thunk)
-> Eval (HashMap Text (Hideable Thunk))
forall (f :: * -> *) a. Applicative f => a -> f a
pure HashMap Text (Hideable Thunk)
o
proj Value
v = Text -> Value -> Eval (HashMap Text (Hideable Thunk))
forall a. Text -> Value -> Eval a
throwTypeMismatch Text
"object" Value
v
inj :: HashMap Text (Hideable Thunk) -> Value
inj = HashMap Text (Hideable Thunk) -> Value
VObj
instance {-# OVERLAPS #-} (HasValue a, HasValue b) => HasValue (a -> b) where
proj :: Value -> Eval (a -> b)
proj Value
v = Text -> Value -> Eval (a -> b)
forall a. Text -> Value -> Eval a
throwTypeMismatch Text
"impossible" Value
v
inj :: (a -> b) -> Value
inj a -> b
f = (Thunk -> Eval Value) -> Value
VFun ((Thunk -> Eval Value) -> Value) -> (Thunk -> Eval Value) -> Value
forall a b. (a -> b) -> a -> b
$ \Thunk
x -> Thunk -> Eval Value
force Thunk
x Eval Value -> (Value -> Eval Value) -> Eval Value
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (a -> Value) -> Eval a -> Eval Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (b -> Value
forall a. HasValue a => a -> Value
inj (b -> Value) -> (a -> b) -> a -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) (Eval a -> Eval Value) -> (Value -> Eval a) -> Value -> Eval Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Eval a
forall a. HasValue a => Value -> Eval a
proj
instance {-# OVERLAPS #-} (HasValue a, HasValue b, HasValue c) => HasValue (a -> b -> c) where
proj :: Value -> Eval (a -> b -> c)
proj Value
v = Text -> Value -> Eval (a -> b -> c)
forall a. Text -> Value -> Eval a
throwTypeMismatch Text
"impossible" Value
v
inj :: (a -> b -> c) -> Value
inj a -> b -> c
f = (a -> Value) -> Value
forall a. HasValue a => a -> Value
inj ((a -> Value) -> Value) -> (a -> Value) -> Value
forall a b. (a -> b) -> a -> b
$ \a
x -> (b -> c) -> Value
forall a. HasValue a => a -> Value
inj (a -> b -> c
f a
x)
instance {-# OVERLAPS #-} (HasValue a, HasValue b) => HasValue (a -> Eval b) where
proj :: Value -> Eval (a -> Eval b)
proj (VFun Thunk -> Eval Value
f) = (a -> Eval b) -> Eval (a -> Eval b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((a -> Eval b) -> Eval (a -> Eval b))
-> (a -> Eval b) -> Eval (a -> Eval b)
forall a b. (a -> b) -> a -> b
$ \a
x -> do
Value
r <- Thunk -> Eval Value
f (Value -> Thunk
mkThunk' (Value -> Thunk) -> Value -> Thunk
forall a b. (a -> b) -> a -> b
$ a -> Value
forall a. HasValue a => a -> Value
inj a
x)
Value -> Eval b
forall a. HasValue a => Value -> Eval a
proj Value
r
proj (VClos Fun
f Env
env) = (a -> Eval b) -> Eval (a -> Eval b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((a -> Eval b) -> Eval (a -> Eval b))
-> (a -> Eval b) -> Eval (a -> Eval b)
forall a b. (a -> b) -> a -> b
$ \a
x -> do
Value
r <- Ctx -> Fun -> [Arg Thunk] -> Eval Value
evalClos (Env -> Ctx
ctx Env
env) Fun
f ([Arg Thunk] -> Eval Value) -> [Arg Thunk] -> Eval Value
forall a b. (a -> b) -> a -> b
$ [Thunk -> Arg Thunk
forall a. a -> Arg a
Pos (Thunk -> Arg Thunk) -> Thunk -> Arg Thunk
forall a b. (a -> b) -> a -> b
$ Value -> Thunk
mkThunk' (Value -> Thunk) -> Value -> Thunk
forall a b. (a -> b) -> a -> b
$ a -> Value
forall a. HasValue a => a -> Value
inj a
x]
Value -> Eval b
forall a. HasValue a => Value -> Eval a
proj Value
r
proj Value
v = Text -> Value -> Eval (a -> Eval b)
forall a. Text -> Value -> Eval a
throwTypeMismatch Text
"function" Value
v
inj :: (a -> Eval b) -> Value
inj a -> Eval b
f = (Thunk -> Eval Value) -> Value
VFun ((Thunk -> Eval Value) -> Value) -> (Thunk -> Eval Value) -> Value
forall a b. (a -> b) -> a -> b
$ \Thunk
v -> Thunk -> Eval a
forall a. HasValue a => Thunk -> Eval a
proj' Thunk
v Eval a -> (a -> Eval Value) -> Eval Value
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (b -> Value) -> Eval b -> Eval Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> Value
forall a. HasValue a => a -> Value
inj (Eval b -> Eval Value) -> (a -> Eval b) -> a -> Eval Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Eval b
f
instance {-# OVERLAPS #-} (HasValue a, HasValue b, HasValue c) => HasValue (a -> b -> Eval c) where
proj :: Value -> Eval (a -> b -> Eval c)
proj (VFun Thunk -> Eval Value
f) = (a -> b -> Eval c) -> Eval (a -> b -> Eval c)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((a -> b -> Eval c) -> Eval (a -> b -> Eval c))
-> (a -> b -> Eval c) -> Eval (a -> b -> Eval c)
forall a b. (a -> b) -> a -> b
$ \a
x b
y -> do
VFun Thunk -> Eval Value
g <- Thunk -> Eval Value
f (Value -> Thunk
mkThunk' (Value -> Thunk) -> Value -> Thunk
forall a b. (a -> b) -> a -> b
$ a -> Value
forall a. HasValue a => a -> Value
inj a
x)
Value
r <- Thunk -> Eval Value
g (Value -> Thunk
mkThunk' (Value -> Thunk) -> Value -> Thunk
forall a b. (a -> b) -> a -> b
$ b -> Value
forall a. HasValue a => a -> Value
inj b
y)
Value -> Eval c
forall a. HasValue a => Value -> Eval a
proj Value
r
proj (VClos Fun
f Env
env) = (a -> b -> Eval c) -> Eval (a -> b -> Eval c)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((a -> b -> Eval c) -> Eval (a -> b -> Eval c))
-> (a -> b -> Eval c) -> Eval (a -> b -> Eval c)
forall a b. (a -> b) -> a -> b
$ \a
x b
y -> do
Value
r <- Ctx -> Fun -> [Arg Thunk] -> Eval Value
evalClos (Env -> Ctx
ctx Env
env) Fun
f ([Arg Thunk] -> Eval Value) -> [Arg Thunk] -> Eval Value
forall a b. (a -> b) -> a -> b
$ Thunk -> Arg Thunk
forall a. a -> Arg a
Pos (Thunk -> Arg Thunk) -> (Value -> Thunk) -> Value -> Arg Thunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Thunk
mkThunk' (Value -> Arg Thunk) -> [Value] -> [Arg Thunk]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a -> Value
forall a. HasValue a => a -> Value
inj a
x, b -> Value
forall a. HasValue a => a -> Value
inj b
y]
Value -> Eval c
forall a. HasValue a => Value -> Eval a
proj Value
r
proj Value
v = Text -> Value -> Eval (a -> b -> Eval c)
forall a. Text -> Value -> Eval a
throwTypeMismatch Text
"function" Value
v
inj :: (a -> b -> Eval c) -> Value
inj a -> b -> Eval c
f = (a -> Value) -> Value
forall a. HasValue a => a -> Value
inj ((a -> Value) -> Value) -> (a -> Value) -> Value
forall a b. (a -> b) -> a -> b
$ \a
x -> (b -> Eval c) -> Value
forall a. HasValue a => a -> Value
inj (a -> b -> Eval c
f a
x)
throwTypeMismatch :: Text -> Value -> Eval a
throwTypeMismatch :: forall a. Text -> Value -> Eval a
throwTypeMismatch Text
expected =
EvalError -> Eval a
forall a. EvalError -> Eval a
throwE
(EvalError -> Eval a) -> (Value -> EvalError) -> Value -> Eval a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> EvalError
TypeMismatch Text
expected
(Text -> EvalError) -> (Value -> Text) -> Value -> EvalError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Text
valueType
inj' ::
(HasValue a, HasValue b) =>
(a -> b) ->
(Value -> Eval Value)
inj' :: forall a b.
(HasValue a, HasValue b) =>
(a -> b) -> Value -> Eval Value
inj' a -> b
f Value
v = b -> Value
forall a. HasValue a => a -> Value
inj (b -> Value) -> (a -> b) -> a -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f (a -> Value) -> Eval a -> Eval Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Eval a
forall a. HasValue a => Value -> Eval a
proj Value
v
inj'' ::
(HasValue a, HasValue b, HasValue c) =>
(a -> b -> c) ->
Value ->
Value ->
Eval Value
inj'' :: forall a b c.
(HasValue a, HasValue b, HasValue c) =>
(a -> b -> c) -> Value -> Value -> Eval Value
inj'' a -> b -> c
f Value
v1 Value
v2 = c -> Value
forall a. HasValue a => a -> Value
inj (c -> Value) -> Eval c -> Eval Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> b -> c) -> Eval a -> Eval b -> Eval c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> b -> c
f (Value -> Eval a
forall a. HasValue a => Value -> Eval a
proj Value
v1) (Value -> Eval b
forall a. HasValue a => Value -> Eval a
proj Value
v2)