{-# LANGUAGE DeriveGeneric #-}

module Dhall.Syntax.FunctionBinding
    ( FunctionBinding(..)
    , makeFunctionBinding

      -- * Optics
    , functionBindingExprs
    ) where

import                Data.Text         (Text)
import {-# SOURCE #-} Dhall.Syntax.Expr (Expr)
import                GHC.Generics      (Generic)

-- | Record the label of a function or a function-type expression
--
-- For example,
--
-- > λ({- A -} a {- B -} : {- C -} T) -> e
--
-- … will be instantiated as follows:
--
-- * @functionBindingSrc0@ corresponds to the @A@ comment
-- * @functionBindingVariable@ is @a@
-- * @functionBindingSrc1@ corresponds to the @B@ comment
-- * @functionBindingSrc2@ corresponds to the @C@ comment
-- * @functionBindingAnnotation@ is @T@
data FunctionBinding s a = FunctionBinding
    { FunctionBinding s a -> Maybe s
functionBindingSrc0 :: Maybe s
    , FunctionBinding s a -> Text
functionBindingVariable :: Text
    , FunctionBinding s a -> Maybe s
functionBindingSrc1 :: Maybe s
    , FunctionBinding s a -> Maybe s
functionBindingSrc2 :: Maybe s
    , FunctionBinding s a -> Expr s a
functionBindingAnnotation :: Expr s a
    } deriving (forall x. FunctionBinding s a -> Rep (FunctionBinding s a) x)
-> (forall x. Rep (FunctionBinding s a) x -> FunctionBinding s a)
-> Generic (FunctionBinding s a)
forall x. Rep (FunctionBinding s a) x -> FunctionBinding s a
forall x. FunctionBinding s a -> Rep (FunctionBinding s a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall s a x. Rep (FunctionBinding s a) x -> FunctionBinding s a
forall s a x. FunctionBinding s a -> Rep (FunctionBinding s a) x
$cto :: forall s a x. Rep (FunctionBinding s a) x -> FunctionBinding s a
$cfrom :: forall s a x. FunctionBinding s a -> Rep (FunctionBinding s a) x
Generic

-- | Smart constructor for 'FunctionBinding' with no src information
makeFunctionBinding :: Text -> Expr s a -> FunctionBinding s a
makeFunctionBinding :: Text -> Expr s a -> FunctionBinding s a
makeFunctionBinding Text
l Expr s a
t = Maybe s
-> Text -> Maybe s -> Maybe s -> Expr s a -> FunctionBinding s a
forall s a.
Maybe s
-> Text -> Maybe s -> Maybe s -> Expr s a -> FunctionBinding s a
FunctionBinding Maybe s
forall a. Maybe a
Nothing Text
l Maybe s
forall a. Maybe a
Nothing Maybe s
forall a. Maybe a
Nothing Expr s a
t

{-| Traverse over the immediate 'Expr' children in a 'FunctionBinding'.
-}
functionBindingExprs
    :: Applicative f
    => (Expr s a -> f (Expr s b))
    -> FunctionBinding s a -> f (FunctionBinding s b)
functionBindingExprs :: (Expr s a -> f (Expr s b))
-> FunctionBinding s a -> f (FunctionBinding s b)
functionBindingExprs Expr s a -> f (Expr s b)
f (FunctionBinding Maybe s
s0 Text
label Maybe s
s1 Maybe s
s2 Expr s a
type_) =
    Maybe s
-> Text -> Maybe s -> Maybe s -> Expr s b -> FunctionBinding s b
forall s a.
Maybe s
-> Text -> Maybe s -> Maybe s -> Expr s a -> FunctionBinding s a
FunctionBinding
        (Maybe s
 -> Text -> Maybe s -> Maybe s -> Expr s b -> FunctionBinding s b)
-> f (Maybe s)
-> f (Text
      -> Maybe s -> Maybe s -> Expr s b -> FunctionBinding s b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe s -> f (Maybe s)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe s
s0
        f (Text -> Maybe s -> Maybe s -> Expr s b -> FunctionBinding s b)
-> f Text
-> f (Maybe s -> Maybe s -> Expr s b -> FunctionBinding s b)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> f Text
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
label
        f (Maybe s -> Maybe s -> Expr s b -> FunctionBinding s b)
-> f (Maybe s) -> f (Maybe s -> Expr s b -> FunctionBinding s b)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe s -> f (Maybe s)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe s
s1
        f (Maybe s -> Expr s b -> FunctionBinding s b)
-> f (Maybe s) -> f (Expr s b -> FunctionBinding s b)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe s -> f (Maybe s)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe s
s2
        f (Expr s b -> FunctionBinding s b)
-> f (Expr s b) -> f (FunctionBinding s b)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Expr s a -> f (Expr s b)
f Expr s a
type_
{-# INLINABLE functionBindingExprs #-}