{-# LANGUAGE OverloadedStrings, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses,
    TypeFamilies, GADTs, GeneralizedNewtypeDeriving, StandaloneDeriving #-}
{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
-- |
-- Module: Data.Greskell.GTraversal
-- Description: Gremlin traversal/step types.
-- Maintainer: Toshio Ito <debug.ito@gmail.com>
--
-- This module defines 'GTraversal', greskell counterpart of
-- @GraphTraversal@ class object, and a DSL of composing graph
-- traversal steps.
module Data.Greskell.GTraversal
       ( -- * Types
         -- ** GraphTraversal and others
         GTraversal(..),
         GraphTraversal,
         ToGTraversal(..),
         Walk,
         GraphTraversalSource,
         -- ** Walk types
         WalkType,
         Filter,
         Transform,
         SideEffect,
         Lift,
         Split,
         -- * GraphTraversalSource
         source,
         sV,
         sV',
         sE,
         sE',
         sAddV,
         sAddV',
         -- * GTraversal
         (&.),
         ($.),
         (<$.>),
         (<*.>),
         gIterate,
         unsafeGTraversal,
         -- * Walk/Steps

         -- |
         -- Functions for TinkerPop graph traversal steps.
         -- __For now greskell does not cover all graph traversal steps.__
         -- If you want some steps added, just open an issue.
         --
         -- There may be multiple versions of Haskell functions for a
         -- single step. This is because Gremlin steps are too
         -- polymorphic for Haskell. greskell should be type-safe so
         -- that incorrect combination of steps is detected in compile
         -- time.

         -- ** Low-level functions
         unsafeWalk,
         modulateWith,
         -- ** Filter steps
         gIdentity,
         gIdentity',
         gFilter,
         gCyclicPath,
         gCyclicPath',
         gSimplePath,
         gSimplePath',
         -- ** Is step
         gIs,
         gIs',
         gIsP,
         gIsP',
         -- ** Has steps
         gHas1,
         gHas1',
         gHas2,
         gHas2',
         gHas2P,
         gHas2P',
         gHasLabel,
         gHasLabel',
         gHasLabelP,
         gHasLabelP',
         gHasId,
         gHasId',
         gHasIdP,
         gHasIdP',
         gHasKey,
         gHasKey',
         gHasKeyP,
         gHasKeyP',
         gHasValue,
         gHasValue',
         gHasValueP,
         gHasValueP',
         -- ** Logic steps
         gAnd,
         gOr,
         gNot,
         -- ** Where step
         gWhereP1,
         gWhereP1',
         gWhereP2,
         gWhereP2',
         -- ** Sorting steps
         gOrder,
         -- ** Paging steps
         gRange,
         gLimit,
         gTail,
         gSkip,
         -- ** Repeat step
         gRepeat,
         gTimes,
         gUntilHead,
         gUntilTail,
         gEmitHead,
         gEmitTail,
         gEmitHeadT,
         gEmitTailT,
         gLoops,
         RepeatUntil(..),
         RepeatEmit(..),
         RepeatPos(..),
         RepeatLabel(..),
         -- ** Branching steps
         gLocal,
         gUnion,
         gCoalesce,
         gChoose3,
         -- ** Barrier steps
         gBarrier,
         gDedup,
         gDedupN,
         -- ** Transformation steps
         gFlatMap,
         gFlatMap',
         gV,
         gV',
         gConstant,
         gProject,
         -- ** As step
         gAs,
         -- ** Accessor steps
         gValues,
         gProperties,
         gId,
         gLabel,
         gValueMap,
         gSelect1,
         gSelectN,
         gSelectBy1,
         gSelectByN,
         gUnfold,
         gPath,
         gPathBy,
         -- ** Summarizing steps
         gFold,
         gCount,
         -- ** Graph traversal steps
         gOut,
         gOut',
         gOutE,
         gOutE',
         gOutV,
         gOutV',
         gIn,
         gIn',
         gInE,
         gInE',
         gInV,
         gInV',
         -- ** Match step
         gMatch,
         MatchPattern(..),
         mPattern,
         MatchResult,
         -- ** Side-effect steps
         gSideEffect,
         gSideEffect',
         -- ** Graph manipulation steps
         gAddV,
         gAddV',
         gAddE,
         gAddE',
         AddAnchor,
         gFrom,
         gTo,
         gDrop,
         gDropP,
         gProperty,
         gPropertyV,
         -- ** @.by@ steps
         
         -- | @.by@ steps are not 'Walk' on their own because they are
         -- always used in conjunction with other steps like 'gOrder'.
         ByProjection(..),
         ProjectionLike(..),
         ByComparator(..),
         LabeledByProjection(..),
         gBy,
         gBy1,
         gBy2,
         gByL,
         -- * Only for tests
         showWalkType,
         showLift,
         showSplit
       ) where

import Control.Applicative ((<$>), (<*>))
import Control.Category (Category, (>>>))
-- (below) to import Category methods without conflict with Prelude
import qualified Control.Category as Category
import Data.Aeson (Value)
import Data.Bifunctor (Bifunctor(bimap))
import Data.Foldable (foldl')
import Data.List.NonEmpty (NonEmpty(..))
import Data.Monoid ((<>), mconcat, Monoid(..))
import Data.Proxy (Proxy)
import Data.Semigroup (Semigroup, sconcat)
import qualified Data.Semigroup as Semigroup
import Data.String (IsString(..))
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL

import Data.Greskell.Graph
  ( Element(..), Property(..), ElementID(..), Vertex, Edge,
    AVertex, AEdge, AVertexProperty,
    T, Key, Cardinality,
    KeyValue(..), Keys(..), Path,
  )
import qualified Data.Greskell.Greskell as Greskell
import Data.Greskell.GraphSON (GValue, FromGraphSON)
import Data.Greskell.Gremlin
  ( Comparator(..),
    P
  )
import Data.Greskell.Greskell
  ( Greskell, ToGreskell(..), unsafeGreskellLazy, unsafeGreskell, unsafeFunCall,
    toGremlinLazy, toGremlin
  )
import Data.Greskell.AsIterator (AsIterator(IteratorItem))
import Data.Greskell.AsLabel (AsLabel, SelectedMap, LabeledP)
import Data.Greskell.Logic (Logic)
import qualified Data.Greskell.Logic as Logic
import Data.Greskell.PMap (PMap, Single)

-- $setup
--
-- >>> :set -XOverloadedStrings
-- >>> import Data.Function ((&))
-- >>> import Data.Greskell.Greskell (gvalueInt)
-- >>> import Data.Greskell.Gremlin (pBetween, pEq, pLte, oDecr, oIncr)
-- >>> import Data.Greskell.Graph (tId, cList, (=:), AVertex, AVertexProperty, (-:))
-- >>> import Data.Greskell.GraphSON (GValueBody(..))

-- | @GraphTraversal@ class object of TinkerPop. It takes data @s@
-- from upstream and emits data @e@ to downstream. Type @c@ is called
-- \"walk type\", a marker to describe the effect of the traversal.
--
-- 'GTraversal' is NOT a 'Category'. Because a @GraphTraversal@ object
-- keeps some context data, the starting (left-most) @GraphTraversal@
-- object controls most of the behavior of entire composition of
-- traversals and steps. This violates 'Category' law.
newtype GTraversal c s e = GTraversal { GTraversal c s e -> Greskell (GraphTraversal c s e)
unGTraversal :: Greskell (GraphTraversal c s e) }
                         deriving (Int -> GTraversal c s e -> ShowS
[GTraversal c s e] -> ShowS
GTraversal c s e -> String
(Int -> GTraversal c s e -> ShowS)
-> (GTraversal c s e -> String)
-> ([GTraversal c s e] -> ShowS)
-> Show (GTraversal c s e)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall c s e. Int -> GTraversal c s e -> ShowS
forall c s e. [GTraversal c s e] -> ShowS
forall c s e. GTraversal c s e -> String
showList :: [GTraversal c s e] -> ShowS
$cshowList :: forall c s e. [GTraversal c s e] -> ShowS
show :: GTraversal c s e -> String
$cshow :: forall c s e. GTraversal c s e -> String
showsPrec :: Int -> GTraversal c s e -> ShowS
$cshowsPrec :: forall c s e. Int -> GTraversal c s e -> ShowS
Show)

-- | Unsafely convert output type.
instance Functor (GTraversal c s) where
  fmap :: (a -> b) -> GTraversal c s a -> GTraversal c s b
fmap a -> b
f (GTraversal Greskell (GraphTraversal c s a)
g) = Greskell (GraphTraversal c s b) -> GTraversal c s b
forall c s e. Greskell (GraphTraversal c s e) -> GTraversal c s e
GTraversal (Greskell (GraphTraversal c s b) -> GTraversal c s b)
-> Greskell (GraphTraversal c s b) -> GTraversal c s b
forall a b. (a -> b) -> a -> b
$ (GraphTraversal c s a -> GraphTraversal c s b)
-> Greskell (GraphTraversal c s a)
-> Greskell (GraphTraversal c s b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b) -> GraphTraversal c s a -> GraphTraversal c s b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f) Greskell (GraphTraversal c s a)
g

-- | Unsafely convert input and output types.
instance Bifunctor (GTraversal c) where
  bimap :: (a -> b) -> (c -> d) -> GTraversal c a c -> GTraversal c b d
bimap a -> b
f1 c -> d
f2 (GTraversal Greskell (GraphTraversal c a c)
g) = Greskell (GraphTraversal c b d) -> GTraversal c b d
forall c s e. Greskell (GraphTraversal c s e) -> GTraversal c s e
GTraversal (Greskell (GraphTraversal c b d) -> GTraversal c b d)
-> Greskell (GraphTraversal c b d) -> GTraversal c b d
forall a b. (a -> b) -> a -> b
$ (GraphTraversal c a c -> GraphTraversal c b d)
-> Greskell (GraphTraversal c a c)
-> Greskell (GraphTraversal c b d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b)
-> (c -> d) -> GraphTraversal c a c -> GraphTraversal c b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap a -> b
f1 c -> d
f2) Greskell (GraphTraversal c a c)
g

-- | Unwrap 'GTraversal' data constructor.
instance ToGreskell (GTraversal c s e) where
  type GreskellReturn (GTraversal c s e) = GraphTraversal c s e
  toGreskell :: GTraversal c s e -> Greskell (GreskellReturn (GTraversal c s e))
toGreskell = GTraversal c s e -> Greskell (GreskellReturn (GTraversal c s e))
forall c s e. GTraversal c s e -> Greskell (GraphTraversal c s e)
unGTraversal

-- | Phantom type for @GraphTraversal@ class. In greskell, we usually
-- use 'GTraversal' instead of 'Greskell' 'GraphTraversal'.
data GraphTraversal c s e = GraphTraversal
                          deriving (Int -> GraphTraversal c s e -> ShowS
[GraphTraversal c s e] -> ShowS
GraphTraversal c s e -> String
(Int -> GraphTraversal c s e -> ShowS)
-> (GraphTraversal c s e -> String)
-> ([GraphTraversal c s e] -> ShowS)
-> Show (GraphTraversal c s e)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall c s e. Int -> GraphTraversal c s e -> ShowS
forall c s e. [GraphTraversal c s e] -> ShowS
forall c s e. GraphTraversal c s e -> String
showList :: [GraphTraversal c s e] -> ShowS
$cshowList :: forall c s e. [GraphTraversal c s e] -> ShowS
show :: GraphTraversal c s e -> String
$cshow :: forall c s e. GraphTraversal c s e -> String
showsPrec :: Int -> GraphTraversal c s e -> ShowS
$cshowsPrec :: forall c s e. Int -> GraphTraversal c s e -> ShowS
Show)

-- | 'GraphTraversal' is an Iterator.
instance AsIterator (GraphTraversal c s e) where
  type IteratorItem (GraphTraversal c s e) = e

-- | Unsafely convert output type.
instance Functor (GraphTraversal c s) where
  fmap :: (a -> b) -> GraphTraversal c s a -> GraphTraversal c s b
fmap a -> b
_ GraphTraversal c s a
GraphTraversal = GraphTraversal c s b
forall c s e. GraphTraversal c s e
GraphTraversal

-- | Unsafely convert input and output types.
instance Bifunctor (GraphTraversal c) where
  bimap :: (a -> b)
-> (c -> d) -> GraphTraversal c a c -> GraphTraversal c b d
bimap a -> b
_ c -> d
_ GraphTraversal c a c
GraphTraversal = GraphTraversal c b d
forall c s e. GraphTraversal c s e
GraphTraversal

-- | Types that can convert to 'GTraversal'.
class ToGTraversal g where
  toGTraversal :: WalkType c => g c s e -> GTraversal c s e
  liftWalk :: (WalkType from, WalkType to, Lift from to) => g from s e -> g to s e
  -- ^ Lift 'WalkType' @from@ to @to@. Use this for type matching.
  
  unsafeCastStart :: WalkType c => g c s1 e -> g c s2 e
  -- ^ Unsafely cast the start type @s1@ into @s2@.
  --
  -- It is recommended that @s2@ is coercible to @s1@ in terms of
  -- 'FromGraphSON'. That is, if @s2@ can parse a 'GValue', @s1@
  -- should also be able to parse that 'GValue'.
  --
  -- @since 1.0.0.0

  unsafeCastEnd :: WalkType c => g c s e1 -> g c s e2
  -- ^ Unsafely cast the end type @e1@ into @e2@. See
  -- 'unsafeCastStart'.
  --
  -- @since 1.0.0.0

instance ToGTraversal GTraversal where
  toGTraversal :: GTraversal c s e -> GTraversal c s e
toGTraversal = GTraversal c s e -> GTraversal c s e
forall a. a -> a
id
  liftWalk :: GTraversal from s e -> GTraversal to s e
liftWalk (GTraversal Greskell (GraphTraversal from s e)
g) = Greskell (GraphTraversal to s e) -> GTraversal to s e
forall c s e. Greskell (GraphTraversal c s e) -> GTraversal c s e
GTraversal (Greskell (GraphTraversal to s e) -> GTraversal to s e)
-> Greskell (GraphTraversal to s e) -> GTraversal to s e
forall a b. (a -> b) -> a -> b
$ Text -> Greskell (GraphTraversal to s e)
forall a. Text -> Greskell a
unsafeGreskellLazy (Text -> Greskell (GraphTraversal to s e))
-> Text -> Greskell (GraphTraversal to s e)
forall a b. (a -> b) -> a -> b
$ Greskell (GraphTraversal from s e) -> Text
forall a. ToGreskell a => a -> Text
toGremlinLazy Greskell (GraphTraversal from s e)
g
  unsafeCastStart :: GTraversal c s1 e -> GTraversal c s2 e
unsafeCastStart (GTraversal Greskell (GraphTraversal c s1 e)
g) = Greskell (GraphTraversal c s2 e) -> GTraversal c s2 e
forall c s e. Greskell (GraphTraversal c s e) -> GTraversal c s e
GTraversal (Greskell (GraphTraversal c s2 e) -> GTraversal c s2 e)
-> Greskell (GraphTraversal c s2 e) -> GTraversal c s2 e
forall a b. (a -> b) -> a -> b
$ Text -> Greskell (GraphTraversal c s2 e)
forall a. Text -> Greskell a
unsafeGreskellLazy (Text -> Greskell (GraphTraversal c s2 e))
-> Text -> Greskell (GraphTraversal c s2 e)
forall a b. (a -> b) -> a -> b
$ Greskell (GraphTraversal c s1 e) -> Text
forall a. ToGreskell a => a -> Text
toGremlinLazy Greskell (GraphTraversal c s1 e)
g
  unsafeCastEnd :: GTraversal c s e1 -> GTraversal c s e2
unsafeCastEnd (GTraversal Greskell (GraphTraversal c s e1)
g) = Greskell (GraphTraversal c s e2) -> GTraversal c s e2
forall c s e. Greskell (GraphTraversal c s e) -> GTraversal c s e
GTraversal (Greskell (GraphTraversal c s e2) -> GTraversal c s e2)
-> Greskell (GraphTraversal c s e2) -> GTraversal c s e2
forall a b. (a -> b) -> a -> b
$ Text -> Greskell (GraphTraversal c s e2)
forall a. Text -> Greskell a
unsafeGreskellLazy (Text -> Greskell (GraphTraversal c s e2))
-> Text -> Greskell (GraphTraversal c s e2)
forall a b. (a -> b) -> a -> b
$ Greskell (GraphTraversal c s e1) -> Text
forall a. ToGreskell a => a -> Text
toGremlinLazy Greskell (GraphTraversal c s e1)
g

-- | A chain of one or more Gremlin steps. Like 'GTraversal', type @s@
-- is the input, type @e@ is the output, and type @c@ is a marker to
-- describe the step.
--
-- 'Walk' represents a chain of method calls such as
-- @.has(x).outE()@. Because this is not a Gremlin (Groovy)
-- expression, we use bare 'Walk', not 'Greskell' 'Walk'.
--
-- 'Walk' is a 'Category'. You can use functions from
-- "Control.Category" to compose 'Walk's. This is equivalent to making
-- a chain of method calls in Gremlin.
--
-- 'Walk' is not an 'Eq', because it's difficult to define true
-- equality between Gremlin method calls. If we define it naively, it
-- might have conflict with 'Category' law.
newtype Walk c s e = Walk TL.Text
                    deriving (Int -> Walk c s e -> ShowS
[Walk c s e] -> ShowS
Walk c s e -> String
(Int -> Walk c s e -> ShowS)
-> (Walk c s e -> String)
-> ([Walk c s e] -> ShowS)
-> Show (Walk c s e)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall c s e. Int -> Walk c s e -> ShowS
forall c s e. [Walk c s e] -> ShowS
forall c s e. Walk c s e -> String
showList :: [Walk c s e] -> ShowS
$cshowList :: forall c s e. [Walk c s e] -> ShowS
show :: Walk c s e -> String
$cshow :: forall c s e. Walk c s e -> String
showsPrec :: Int -> Walk c s e -> ShowS
$cshowsPrec :: forall c s e. Int -> Walk c s e -> ShowS
Show)

-- | 'id' is 'gIdentity'.
instance WalkType c => Category (Walk c) where
  id :: Walk c a a
id = Walk c a a
forall c s. WalkType c => Walk c s s
gIdentity
  (Walk Text
bc) . :: Walk c b c -> Walk c a b -> Walk c a c
. (Walk Text
ab) = Text -> Walk c a c
forall c s e. Text -> Walk c s e
Walk (Text
ab Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
bc)

-- | Based on 'Category'. 'Semigroup.<>' is 'Category.>>>'.
instance WalkType c => Semigroup (Walk c s s) where
  <> :: Walk c s s -> Walk c s s -> Walk c s s
(<>) = Walk c s s -> Walk c s s -> Walk c s s
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
(Category.>>>)

-- | Based on 'Category' and 'Semigroup'. 'mempty' is 'Category.id'.
instance WalkType c => Monoid (Walk c s s) where
  mempty :: Walk c s s
mempty = Walk c s s
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
Category.id
  mappend :: Walk c s s -> Walk c s s -> Walk c s s
mappend = Walk c s s -> Walk c s s -> Walk c s s
forall a. Semigroup a => a -> a -> a
(Semigroup.<>)

-- | Unsafely convert output type
instance Functor (Walk c s) where
  fmap :: (a -> b) -> Walk c s a -> Walk c s b
fmap a -> b
_ (Walk Text
t) = Text -> Walk c s b
forall c s e. Text -> Walk c s e
Walk Text
t

-- | Unsafely convert input and output types.
instance Bifunctor (Walk c) where
  bimap :: (a -> b) -> (c -> d) -> Walk c a c -> Walk c b d
bimap a -> b
_ c -> d
_ (Walk Text
t) = Text -> Walk c b d
forall c s e. Text -> Walk c s e
Walk Text
t

-- | To convert a 'Walk' to 'GTraversal', it calls its static method
-- version on @__@ class.
instance ToGTraversal Walk where
  toGTraversal :: Walk c s e -> GTraversal c s e
toGTraversal (Walk Text
t) = Greskell (GraphTraversal c s e) -> GTraversal c s e
forall c s e. Greskell (GraphTraversal c s e) -> GTraversal c s e
GTraversal (Greskell (GraphTraversal c s e) -> GTraversal c s e)
-> Greskell (GraphTraversal c s e) -> GTraversal c s e
forall a b. (a -> b) -> a -> b
$ Text -> Greskell (GraphTraversal c s e)
forall a. Text -> Greskell a
unsafeGreskellLazy (Text
"__" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
t)
  liftWalk :: Walk from s e -> Walk to s e
liftWalk (Walk Text
t) = Text -> Walk to s e
forall c s e. Text -> Walk c s e
Walk Text
t
  unsafeCastStart :: Walk c s1 e -> Walk c s2 e
unsafeCastStart (Walk Text
t) = Text -> Walk c s2 e
forall c s e. Text -> Walk c s e
Walk Text
t
  unsafeCastEnd :: Walk c s e1 -> Walk c s e2
unsafeCastEnd (Walk Text
t) = Text -> Walk c s e2
forall c s e. Text -> Walk c s e
Walk Text
t

-- | The 'Walk' is first converted to 'GTraversal', and it's converted
-- to 'Greskell'.
instance WalkType c => ToGreskell (Walk c s e) where
  type GreskellReturn (Walk c s e) = GraphTraversal c s e
  toGreskell :: Walk c s e -> Greskell (GreskellReturn (Walk c s e))
toGreskell = GTraversal c s e -> Greskell (GraphTraversal c s e)
forall a. ToGreskell a => a -> Greskell (GreskellReturn a)
toGreskell (GTraversal c s e -> Greskell (GraphTraversal c s e))
-> (Walk c s e -> GTraversal c s e)
-> Walk c s e
-> Greskell (GraphTraversal c s e)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Walk c s e -> GTraversal c s e
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> GTraversal c s e
toGTraversal

-- | Class of phantom type markers to describe the effect of the
-- walk/traversals.
class WalkType t where
  -- | Only for tests.
  showWalkType :: Proxy t -> String

-- | WalkType for filtering steps.
--
-- A filtering step is a step that does filtering only. It takes input
-- and emits some of them without any modification, reordering,
-- traversal actions, or side-effects. Filtering decision must be
-- solely based on each element.
--
-- A 'Walk' @w@ is 'Filter' type iff:
--
-- > (gSideEffect w == gIdentity) AND (gFilter w == w)
--
-- If 'Walk's @w1@ and @w2@ are 'Filter' type, then
-- 
-- > gAnd [w1, w2] == w1 >>> w2 == w2 >>> w1
data Filter

instance WalkType Filter where
  showWalkType :: Proxy Filter -> String
showWalkType Proxy Filter
_ = String
"Filter"

-- | WalkType for steps without any side-effects. This includes
-- transformations, reordring, injections and graph traversal actions.
--
-- A 'Walk' @w@ is 'Transform' type iff:
--
-- > gSideEffect w == gIdentity
--
-- Obviously, every 'Filter' type 'Walk's are also 'Transform' type.
data Transform

instance WalkType Transform where
  showWalkType :: Proxy Transform -> String
showWalkType Proxy Transform
_ = String
"Transform"

-- | WalkType for steps that may have side-effects.
--
-- A side-effect here means manipulation of the \"sideEffect\" in
-- Gremlin context (i.e. the stash of data kept in a Traversal
-- object), as well as interaction with the world outside the
-- Traversal object.
--
-- For example, the following steps (in Gremlin) all have
-- side-effects.
--
-- > .addE('label')
-- > .aggregate('x')
-- > .sideEffect(System.out.&println)
-- > .map { some_variable += 1 }
data SideEffect

instance WalkType SideEffect where
  showWalkType :: Proxy SideEffect -> String
showWalkType Proxy SideEffect
_ = String
"SideEffect"

-- | Relation of 'WalkType's where one includes the other. @from@ can
-- be lifted to @to@, because @to@ is more powerful than @from@.
class Lift from to where
  -- | Only for tests.
  showLift :: Proxy from -> Proxy to -> String

genericShowLift :: (WalkType from, WalkType to) => Proxy from -> Proxy to -> String
genericShowLift :: Proxy from -> Proxy to -> String
genericShowLift Proxy from
f Proxy to
t = String
"Lift " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Proxy from -> String
forall t. WalkType t => Proxy t -> String
showWalkType Proxy from
f String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Proxy to -> String
forall t. WalkType t => Proxy t -> String
showWalkType Proxy to
t

instance (WalkType c) => Lift Filter c where
  showLift :: Proxy Filter -> Proxy c -> String
showLift = Proxy Filter -> Proxy c -> String
forall from to.
(WalkType from, WalkType to) =>
Proxy from -> Proxy to -> String
genericShowLift
instance Lift Transform Transform where
  showLift :: Proxy Transform -> Proxy Transform -> String
showLift = Proxy Transform -> Proxy Transform -> String
forall from to.
(WalkType from, WalkType to) =>
Proxy from -> Proxy to -> String
genericShowLift
instance Lift Transform SideEffect where
  showLift :: Proxy Transform -> Proxy SideEffect -> String
showLift = Proxy Transform -> Proxy SideEffect -> String
forall from to.
(WalkType from, WalkType to) =>
Proxy from -> Proxy to -> String
genericShowLift
instance Lift SideEffect SideEffect where
  showLift :: Proxy SideEffect -> Proxy SideEffect -> String
showLift = Proxy SideEffect -> Proxy SideEffect -> String
forall from to.
(WalkType from, WalkType to) =>
Proxy from -> Proxy to -> String
genericShowLift

-- | Relation of 'WalkType's where the child walk @c@ is split from
-- the parent walk @p@.
--
-- When splitting, transformation effect done in the child walk is
-- rolled back (canceled) in the parent walk.
class Split c p where
  -- | Only for tests.
  showSplit :: Proxy c -> Proxy p -> String

genericShowSplit :: (WalkType c, WalkType p) => Proxy c -> Proxy p -> String
genericShowSplit :: Proxy c -> Proxy p -> String
genericShowSplit Proxy c
c Proxy p
p = String
"Split " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Proxy c -> String
forall t. WalkType t => Proxy t -> String
showWalkType Proxy c
c String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Proxy p -> String
forall t. WalkType t => Proxy t -> String
showWalkType Proxy p
p

instance (WalkType p) => Split Filter p where
  showSplit :: Proxy Filter -> Proxy p -> String
showSplit = Proxy Filter -> Proxy p -> String
forall from to.
(WalkType from, WalkType to) =>
Proxy from -> Proxy to -> String
genericShowSplit

-- | 'Transform' effect in the child walk is rolled back in the parent
-- walk.
instance (WalkType p) => Split Transform p where
  showSplit :: Proxy Transform -> Proxy p -> String
showSplit = Proxy Transform -> Proxy p -> String
forall from to.
(WalkType from, WalkType to) =>
Proxy from -> Proxy to -> String
genericShowSplit

-- | 'SideEffect' in the child walk remains in the parent walk.
instance Split SideEffect SideEffect where
  showSplit :: Proxy SideEffect -> Proxy SideEffect -> String
showSplit = Proxy SideEffect -> Proxy SideEffect -> String
forall from to.
(WalkType from, WalkType to) =>
Proxy from -> Proxy to -> String
genericShowSplit


-- | @GraphTraversalSource@ class object of TinkerPop. It is a factory
-- object of 'GraphTraversal's.
data GraphTraversalSource = GraphTraversalSource
                          deriving (Int -> GraphTraversalSource -> ShowS
[GraphTraversalSource] -> ShowS
GraphTraversalSource -> String
(Int -> GraphTraversalSource -> ShowS)
-> (GraphTraversalSource -> String)
-> ([GraphTraversalSource] -> ShowS)
-> Show GraphTraversalSource
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GraphTraversalSource] -> ShowS
$cshowList :: [GraphTraversalSource] -> ShowS
show :: GraphTraversalSource -> String
$cshow :: GraphTraversalSource -> String
showsPrec :: Int -> GraphTraversalSource -> ShowS
$cshowsPrec :: Int -> GraphTraversalSource -> ShowS
Show)


-- | Create 'GraphTraversalSource' from a varible name in Gremlin
--
-- >>> toGremlin $ source "g"
-- "g"
source :: Text -- ^ variable name of 'GraphTraversalSource'
       -> Greskell GraphTraversalSource
source :: Text -> Greskell GraphTraversalSource
source = Text -> Greskell GraphTraversalSource
forall a. Text -> Greskell a
unsafeGreskell

sourceMethod :: Text -> [Greskell a] -> Greskell GraphTraversalSource -> Greskell b
sourceMethod :: Text -> [Greskell a] -> Greskell GraphTraversalSource -> Greskell b
sourceMethod Text
method_name [Greskell a]
args Greskell GraphTraversalSource
src =
  Text -> Greskell b
forall a. Text -> Greskell a
unsafeGreskellLazy (Text -> Greskell b) -> Text -> Greskell b
forall a b. (a -> b) -> a -> b
$ (Greskell GraphTraversalSource -> Text
forall a. ToGreskell a => a -> Text
toGremlinLazy Greskell GraphTraversalSource
src Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> [Text] -> Text
methodCallText Text
method_name ((Greskell a -> Text) -> [Greskell a] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Greskell a -> Text
forall a. ToGreskell a => a -> Text
toGremlin [Greskell a]
args))

-- | @.V()@ method on 'GraphTraversalSource'.
sV :: Vertex v
   => [Greskell (ElementID v)] -- ^ vertex IDs
   -> Greskell GraphTraversalSource
   -> GTraversal Transform () v
sV :: [Greskell (ElementID v)]
-> Greskell GraphTraversalSource -> GTraversal Transform () v
sV [Greskell (ElementID v)]
ids Greskell GraphTraversalSource
src = Greskell (GraphTraversal Transform () v)
-> GTraversal Transform () v
forall c s e. Greskell (GraphTraversal c s e) -> GTraversal c s e
GTraversal (Greskell (GraphTraversal Transform () v)
 -> GTraversal Transform () v)
-> Greskell (GraphTraversal Transform () v)
-> GTraversal Transform () v
forall a b. (a -> b) -> a -> b
$ Text
-> [Greskell (ElementID v)]
-> Greskell GraphTraversalSource
-> Greskell (GraphTraversal Transform () v)
forall a b.
Text -> [Greskell a] -> Greskell GraphTraversalSource -> Greskell b
sourceMethod Text
"V" [Greskell (ElementID v)]
ids Greskell GraphTraversalSource
src

-- | Monomorphic version of 'sV'.
--
-- >>> toGremlin (source "g" & sV' (map (fmap ElementID . gvalueInt) ([1,2,3] :: [Int])))
-- "g.V(1,2,3)"
sV' :: [Greskell (ElementID AVertex)] -- ^ vertex IDs
    -> Greskell GraphTraversalSource
    -> GTraversal Transform () AVertex
sV' :: [Greskell (ElementID AVertex)]
-> Greskell GraphTraversalSource -> GTraversal Transform () AVertex
sV' = [Greskell (ElementID AVertex)]
-> Greskell GraphTraversalSource -> GTraversal Transform () AVertex
forall v.
Vertex v =>
[Greskell (ElementID v)]
-> Greskell GraphTraversalSource -> GTraversal Transform () v
sV

-- | @.E()@ method on 'GraphTraversalSource'.
sE :: Edge e
   => [Greskell (ElementID e)] -- ^ edge IDs
   -> Greskell GraphTraversalSource
   -> GTraversal Transform () e
sE :: [Greskell (ElementID e)]
-> Greskell GraphTraversalSource -> GTraversal Transform () e
sE [Greskell (ElementID e)]
ids Greskell GraphTraversalSource
src = Greskell (GraphTraversal Transform () e)
-> GTraversal Transform () e
forall c s e. Greskell (GraphTraversal c s e) -> GTraversal c s e
GTraversal (Greskell (GraphTraversal Transform () e)
 -> GTraversal Transform () e)
-> Greskell (GraphTraversal Transform () e)
-> GTraversal Transform () e
forall a b. (a -> b) -> a -> b
$ Text
-> [Greskell (ElementID e)]
-> Greskell GraphTraversalSource
-> Greskell (GraphTraversal Transform () e)
forall a b.
Text -> [Greskell a] -> Greskell GraphTraversalSource -> Greskell b
sourceMethod Text
"E" [Greskell (ElementID e)]
ids Greskell GraphTraversalSource
src

-- | Monomorphic version of 'sE'.
--
-- >>> toGremlin (source "g" & sE' (map (fmap ElementID . gvalueInt) ([1] :: [Int])))
-- "g.E(1)"
sE' :: [Greskell (ElementID AEdge)] -- ^ edge IDs
    -> Greskell GraphTraversalSource
    -> GTraversal Transform () AEdge
sE' :: [Greskell (ElementID AEdge)]
-> Greskell GraphTraversalSource -> GTraversal Transform () AEdge
sE' = [Greskell (ElementID AEdge)]
-> Greskell GraphTraversalSource -> GTraversal Transform () AEdge
forall e.
Edge e =>
[Greskell (ElementID e)]
-> Greskell GraphTraversalSource -> GTraversal Transform () e
sE

-- | @.addV()@ method on 'GraphTraversalSource'.
--
-- @since 0.2.0.0
sAddV :: Vertex v
      => Greskell Text -- ^ vertex label
      -> Greskell GraphTraversalSource
      -> GTraversal SideEffect () v
sAddV :: Greskell Text
-> Greskell GraphTraversalSource -> GTraversal SideEffect () v
sAddV Greskell Text
label Greskell GraphTraversalSource
src = Greskell (GraphTraversal SideEffect () v)
-> GTraversal SideEffect () v
forall c s e. Greskell (GraphTraversal c s e) -> GTraversal c s e
GTraversal (Greskell (GraphTraversal SideEffect () v)
 -> GTraversal SideEffect () v)
-> Greskell (GraphTraversal SideEffect () v)
-> GTraversal SideEffect () v
forall a b. (a -> b) -> a -> b
$ Text
-> [Greskell Text]
-> Greskell GraphTraversalSource
-> Greskell (GraphTraversal SideEffect () v)
forall a b.
Text -> [Greskell a] -> Greskell GraphTraversalSource -> Greskell b
sourceMethod Text
"addV" [Greskell Text
label] Greskell GraphTraversalSource
src

-- | Monomorphic version of 'sAddV'.
--
-- >>> toGremlin (source "g" & sAddV' "person")
-- "g.addV(\"person\")"
--
-- @since 0.2.0.0
sAddV' :: Greskell Text -> Greskell GraphTraversalSource -> GTraversal SideEffect () AVertex
sAddV' :: Greskell Text
-> Greskell GraphTraversalSource
-> GTraversal SideEffect () AVertex
sAddV' = Greskell Text
-> Greskell GraphTraversalSource
-> GTraversal SideEffect () AVertex
forall v.
Vertex v =>
Greskell Text
-> Greskell GraphTraversalSource -> GTraversal SideEffect () v
sAddV

-- | Unsafely create 'GTraversal' from the given raw Gremlin script.
--
-- >>> toGremlin $ unsafeGTraversal "g.V().count()"
-- "g.V().count()"
unsafeGTraversal :: Text -> GTraversal c s e
unsafeGTraversal :: Text -> GTraversal c s e
unsafeGTraversal = Greskell (GraphTraversal c s e) -> GTraversal c s e
forall c s e. Greskell (GraphTraversal c s e) -> GTraversal c s e
GTraversal (Greskell (GraphTraversal c s e) -> GTraversal c s e)
-> (Text -> Greskell (GraphTraversal c s e))
-> Text
-> GTraversal c s e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Greskell (GraphTraversal c s e)
forall a. Text -> Greskell a
unsafeGreskell

infixl 1 &.

-- | Apply the 'Walk' to the 'GTraversal'. In Gremlin, this means
-- calling a chain of methods on the Traversal object.
--
-- >>> toGremlin (source "g" & sV' [] &. gValues ["age"])
-- "g.V().values(\"age\")"
(&.) :: GTraversal c a b -> Walk c b d -> GTraversal c a d
(GTraversal Greskell (GraphTraversal c a b)
gt) &. :: GTraversal c a b -> Walk c b d -> GTraversal c a d
&. (Walk Text
twalk) = Greskell (GraphTraversal c a d) -> GTraversal c a d
forall c s e. Greskell (GraphTraversal c s e) -> GTraversal c s e
GTraversal (Greskell (GraphTraversal c a d) -> GTraversal c a d)
-> Greskell (GraphTraversal c a d) -> GTraversal c a d
forall a b. (a -> b) -> a -> b
$ Text -> Greskell (GraphTraversal c a d)
forall a. Text -> Greskell a
unsafeGreskellLazy (Greskell (GraphTraversal c a b) -> Text
forall a. ToGreskell a => a -> Text
toGremlinLazy Greskell (GraphTraversal c a b)
gt Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
twalk)

infixr 0 $.

-- | Same as '&.' with arguments flipped.
--
-- >>> toGremlin (gValues ["age"] $. sV' [] $ source "g")
-- "g.V().values(\"age\")"
($.) :: Walk c b d -> GTraversal c a b -> GTraversal c a d
Walk c b d
gs $. :: Walk c b d -> GTraversal c a b -> GTraversal c a d
$. GTraversal c a b
gt = GTraversal c a b
gt GTraversal c a b -> Walk c b d -> GTraversal c a d
forall c a b d. GTraversal c a b -> Walk c b d -> GTraversal c a d
&. Walk c b d
gs

infixr 0 <$.>

-- | Similar to '<$>', but for '$.'.
--
-- @since 0.2.1.0
(<$.>) :: Functor f => Walk c b d -> f (GTraversal c a b) -> f (GTraversal c a d)
Walk c b d
gs <$.> :: Walk c b d -> f (GTraversal c a b) -> f (GTraversal c a d)
<$.> f (GTraversal c a b)
gt = Walk c b d -> GTraversal c a b -> GTraversal c a d
forall c b d a. Walk c b d -> GTraversal c a b -> GTraversal c a d
($.) Walk c b d
gs (GTraversal c a b -> GTraversal c a d)
-> f (GTraversal c a b) -> f (GTraversal c a d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f (GTraversal c a b)
gt

infixr 0 <*.>

-- | Similar to '<*>', but for '$.'.
--
-- @since 0.2.1.0
(<*.>) :: Applicative f => f (Walk c b d) -> f (GTraversal c a b) -> f (GTraversal c a d)
f (Walk c b d)
gs <*.> :: f (Walk c b d) -> f (GTraversal c a b) -> f (GTraversal c a d)
<*.> f (GTraversal c a b)
gt = Walk c b d -> GTraversal c a b -> GTraversal c a d
forall c b d a. Walk c b d -> GTraversal c a b -> GTraversal c a d
($.) (Walk c b d -> GTraversal c a b -> GTraversal c a d)
-> f (Walk c b d) -> f (GTraversal c a b -> GTraversal c a d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f (Walk c b d)
gs f (GTraversal c a b -> GTraversal c a d)
-> f (GTraversal c a b) -> f (GTraversal c a d)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> f (GTraversal c a b)
gt

-- | @.iterate@ method on @GraphTraversal@.
--
-- 'gIterate' is not a 'Walk' because it's usually used to terminate
-- the method chain of Gremlin steps. The returned 'GTraversal'
-- outputs nothing, thus its end type is '()'.
--
-- >>> toGremlin (source "g" & sAddV' "person" &. gProperty "name" "marko" & gIterate)
-- "g.addV(\"person\").property(\"name\",\"marko\").iterate()"
--
-- @since 1.1.0.0
gIterate :: WalkType c => GTraversal c s e -> GTraversal c s ()
gIterate :: GTraversal c s e -> GTraversal c s ()
gIterate GTraversal c s e
gt = Text -> [Text] -> Walk c e ()
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"iterate" [] Walk c e () -> GTraversal c s e -> GTraversal c s ()
forall c b d a. Walk c b d -> GTraversal c a b -> GTraversal c a d
$. GTraversal c s e
gt

-- -- $walk-steps
-- --

methodCallText :: Text -- ^ method name
               -> [Text] -- ^ args
               -> TL.Text
methodCallText :: Text -> [Text] -> Text
methodCallText Text
name [Text]
args = (Text
"." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Greskell Any -> Text
forall a. ToGreskell a => a -> Text
toGremlinLazy (Greskell Any -> Text) -> Greskell Any -> Text
forall a b. (a -> b) -> a -> b
$ Text -> [Text] -> Greskell Any
forall a. Text -> [Text] -> Greskell a
unsafeFunCall Text
name [Text]
args

-- | Unsafely create a 'Walk' that represents a single method call on
-- a @GraphTraversal@.
--
-- >>> toGremlin (source "g" & sV' [] &. unsafeWalk "valueMap" ["'foo'", "'bar'"])
-- "g.V().valueMap('foo','bar')"
unsafeWalk :: WalkType c
           => Text -- ^ step method name (e.g. "outE")
           -> [Text] -- ^ step method arguments
           -> Walk c s e
unsafeWalk :: Text -> [Text] -> Walk c s e
unsafeWalk Text
name [Text]
args = Text -> Walk c s e
forall c s e. Text -> Walk c s e
Walk (Text -> Walk c s e) -> Text -> Walk c s e
forall a b. (a -> b) -> a -> b
$ Text -> [Text] -> Text
methodCallText Text
name [Text]
args

-- | Optionally modulate the main 'Walk' with some modulating 'Walk's.
--
-- >>> toGremlin (source "g" & sV' [] &. modulateWith (unsafeWalk "path" []) [unsafeWalk "by" ["'name'"], unsafeWalk "by" ["'age'"]])
-- "g.V().path().by('name').by('age')"
modulateWith :: (WalkType c)
             => Walk c s e -- ^ the main 'Walk'
             -> [Walk c e e] -- ^ the modulating 'Walk's
             -> Walk c s e
modulateWith :: Walk c s e -> [Walk c e e] -> Walk c s e
modulateWith Walk c s e
w [] = Walk c s e
w
modulateWith Walk c s e
w (Walk c e e
m:[Walk c e e]
rest) = Walk c s e
w Walk c s e -> Walk c e e -> Walk c s e
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> NonEmpty (Walk c e e) -> Walk c e e
forall a. Semigroup a => NonEmpty a -> a
sconcat (Walk c e e
m Walk c e e -> [Walk c e e] -> NonEmpty (Walk c e e)
forall a. a -> [a] -> NonEmpty a
:| [Walk c e e]
rest)

-- | @.identity@ step.
gIdentity :: WalkType c => Walk c s s
gIdentity :: Walk c s s
gIdentity = Walk Filter s s -> Walk c s s
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter s s -> Walk c s s) -> Walk Filter s s -> Walk c s s
forall a b. (a -> b) -> a -> b
$ Walk Filter s s
forall s. Walk Filter s s
gIdentity'

-- | Monomorphic version of 'gIdentity'.
gIdentity' :: Walk Filter s s
gIdentity' :: Walk Filter s s
gIdentity' = Text -> [Text] -> Walk Filter s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"identity" []

travToG :: (ToGTraversal g, WalkType c) => g c s e -> Text
travToG :: g c s e -> Text
travToG = Greskell (GraphTraversal c s e) -> Text
forall a. ToGreskell a => a -> Text
toGremlin (Greskell (GraphTraversal c s e) -> Text)
-> (g c s e -> Greskell (GraphTraversal c s e)) -> g c s e -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GTraversal c s e -> Greskell (GraphTraversal c s e)
forall c s e. GTraversal c s e -> Greskell (GraphTraversal c s e)
unGTraversal (GTraversal c s e -> Greskell (GraphTraversal c s e))
-> (g c s e -> GTraversal c s e)
-> g c s e
-> Greskell (GraphTraversal c s e)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. g c s e -> GTraversal c s e
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> GTraversal c s e
toGTraversal

-- | @.filter@ step that takes a traversal.
--
-- >>> toGremlin (source "g" & sV' [] &. gFilter (gOut' ["knows"]))
-- "g.V().filter(__.out(\"knows\"))"
gFilter :: (ToGTraversal g, WalkType c, WalkType p, Split c p) => g c s e -> Walk p s s
gFilter :: g c s e -> Walk p s s
gFilter g c s e
walk = Text -> [Text] -> Walk p s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"filter" [g c s e -> Text
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> Text
travToG g c s e
walk]

-- | @.cyclicPath@ step.
--
-- @since 1.0.1.0
gCyclicPath :: (WalkType c) => Walk c a a
gCyclicPath :: Walk c a a
gCyclicPath = Walk Filter a a -> Walk c a a
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk Walk Filter a a
forall s. Walk Filter s s
gCyclicPath'

-- | Monomorphic version of 'gCyclicPath'.
--
-- @since 1.0.1.0
gCyclicPath' :: Walk Filter a a
gCyclicPath' :: Walk Filter a a
gCyclicPath' = Text -> [Text] -> Walk Filter a a
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"cyclicPath" []

-- | @.simplePath@ step.
--
-- @since 1.0.1.0
gSimplePath :: (WalkType c) => Walk c a a
gSimplePath :: Walk c a a
gSimplePath = Walk Filter a a -> Walk c a a
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk Walk Filter a a
forall s. Walk Filter s s
gSimplePath'

-- | Monomorphic version of 'gSimplePath'.
--
-- @since 1.0.1.0
gSimplePath' :: Walk Filter a a
gSimplePath' :: Walk Filter a a
gSimplePath' = Text -> [Text] -> Walk Filter a a
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"simplePath" []

gWherePGeneric :: Maybe (AsLabel a)
               -> Greskell (LabeledP a)
               -> Maybe (ByProjection a b)
               -> Walk Filter x x
gWherePGeneric :: Maybe (AsLabel a)
-> Greskell (LabeledP a)
-> Maybe (ByProjection a b)
-> Walk Filter x x
gWherePGeneric Maybe (AsLabel a)
mstart Greskell (LabeledP a)
p Maybe (ByProjection a b)
mby = Walk Filter x x -> [Walk Filter x x] -> Walk Filter x x
forall c s e.
WalkType c =>
Walk c s e -> [Walk c e e] -> Walk c s e
modulateWith Walk Filter x x
wh [Walk Filter x x]
mods
  where
    wh :: Walk Filter x x
wh = Text -> [Text] -> Walk Filter x x
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"where" ([Text] -> Walk Filter x x) -> [Text] -> Walk Filter x x
forall a b. (a -> b) -> a -> b
$ [Text]
start_args [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Greskell (LabeledP a) -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell (LabeledP a)
p]
    start_args :: [Text]
start_args = [Text] -> (AsLabel a -> [Text]) -> Maybe (AsLabel a) -> [Text]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Text -> [Text]
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> [Text]) -> (AsLabel a -> Text) -> AsLabel a -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AsLabel a -> Text
forall a. ToGreskell a => a -> Text
toGremlin) Maybe (AsLabel a)
mstart
    mods :: [Walk Filter x x]
mods = [Walk Filter x x]
-> (ByProjection a b -> [Walk Filter x x])
-> Maybe (ByProjection a b)
-> [Walk Filter x x]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Walk Filter x x -> [Walk Filter x x]
forall (m :: * -> *) a. Monad m => a -> m a
return (Walk Filter x x -> [Walk Filter x x])
-> (ByProjection a b -> Walk Filter x x)
-> ByProjection a b
-> [Walk Filter x x]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByProjection a b -> Walk Filter x x
forall t a b c. WalkType t => ByProjection a b -> Walk t c c
byStep) Maybe (ByProjection a b)
mby

-- | @.where@ step with @P@ argument only.
--
-- >>> let la = ("a" :: AsLabel AVertex)
-- >>> let age = ("age" :: Key AVertex Int)
-- >>> toGremlin (source "g" & sV' [] &. gAs la &. gOut' [] &. gWhereP1 (pEq la) (Just $ gBy age))
-- "g.V().as(\"a\").out().where(P.eq(\"a\")).by(\"age\")"
--
-- If the 'ByProjection' argument is 'Nothing', comparison is
-- performed on the type @a@. You have to ensure that the comparator
-- included in the 'LabeledP' argument can handle the type
-- @a@. Usually this means the type @a@ should implement Java's
-- @Comparable@ interface (this is true for most Java classes).
--
-- If the 'ByProjection' argument is given, comparison is performed on
-- the projected values of type @b@. So, the type @b@ should implement
-- Java's @Comparable@ interface.
--
-- @since 1.2.0.0
gWhereP1 :: WalkType c
         => Greskell (LabeledP a) -- ^ the @P@ argument for @.where@ step.
         -> Maybe (ByProjection a b) -- ^ optional @.by@ modulation following the @.where@ step.
         -> Walk c a a
gWhereP1 :: Greskell (LabeledP a) -> Maybe (ByProjection a b) -> Walk c a a
gWhereP1 Greskell (LabeledP a)
p Maybe (ByProjection a b)
mby = Walk Filter a a -> Walk c a a
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter a a -> Walk c a a) -> Walk Filter a a -> Walk c a a
forall a b. (a -> b) -> a -> b
$ Greskell (LabeledP a)
-> Maybe (ByProjection a b) -> Walk Filter a a
forall a b.
Greskell (LabeledP a)
-> Maybe (ByProjection a b) -> Walk Filter a a
gWhereP1' Greskell (LabeledP a)
p Maybe (ByProjection a b)
mby

-- | Monomorphic version of 'gWhereP1'.
--
-- @since 1.2.0.0
gWhereP1' :: Greskell (LabeledP a) -> Maybe (ByProjection a b) -> Walk Filter a a
gWhereP1' :: Greskell (LabeledP a)
-> Maybe (ByProjection a b) -> Walk Filter a a
gWhereP1' Greskell (LabeledP a)
p Maybe (ByProjection a b)
mby = Maybe (AsLabel a)
-> Greskell (LabeledP a)
-> Maybe (ByProjection a b)
-> Walk Filter a a
forall a b x.
Maybe (AsLabel a)
-> Greskell (LabeledP a)
-> Maybe (ByProjection a b)
-> Walk Filter x x
gWherePGeneric Maybe (AsLabel a)
forall a. Maybe a
Nothing Greskell (LabeledP a)
p Maybe (ByProjection a b)
mby

-- | @.where@ step with the starting label and @P@ arguments. See also
-- 'gWhereP1'.
--
-- >>> let la = ("a" :: AsLabel AVertex)
-- >>> let lb = ("b" :: AsLabel AVertex)
-- >>> let age = ("age" :: Key AVertex Int)
-- >>> toGremlin (source "g" & sV' [] &. gAs la &. gOut' [] &. gAs lb &. gValues [age] &. gWhereP2 la (pEq lb) Nothing)
-- "g.V().as(\"a\").out().as(\"b\").values(\"age\").where(\"a\",P.eq(\"b\"))"
--
-- @since 1.2.0.0
gWhereP2 :: WalkType c
         => AsLabel a -- ^ the starting label of @.where@.
         -> Greskell (LabeledP a) -- ^ the @P@ argument for @.where@ step.
         -> Maybe (ByProjection a b) -- ^ optional @.by@ modulation following the @.where@ step.
         -> Walk c x x
gWhereP2 :: AsLabel a
-> Greskell (LabeledP a) -> Maybe (ByProjection a b) -> Walk c x x
gWhereP2 AsLabel a
s Greskell (LabeledP a)
p Maybe (ByProjection a b)
b = Walk Filter x x -> Walk c x x
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter x x -> Walk c x x) -> Walk Filter x x -> Walk c x x
forall a b. (a -> b) -> a -> b
$ AsLabel a
-> Greskell (LabeledP a)
-> Maybe (ByProjection a b)
-> Walk Filter x x
forall a b x.
AsLabel a
-> Greskell (LabeledP a)
-> Maybe (ByProjection a b)
-> Walk Filter x x
gWhereP2' AsLabel a
s Greskell (LabeledP a)
p Maybe (ByProjection a b)
b

-- | Monomorphic version of 'gWhereP2'.
--
-- @since 1.2.0.0
gWhereP2' :: AsLabel a -> Greskell (LabeledP a) -> Maybe (ByProjection a b) -> Walk Filter x x
gWhereP2' :: AsLabel a
-> Greskell (LabeledP a)
-> Maybe (ByProjection a b)
-> Walk Filter x x
gWhereP2' AsLabel a
start Greskell (LabeledP a)
p Maybe (ByProjection a b)
mby = Maybe (AsLabel a)
-> Greskell (LabeledP a)
-> Maybe (ByProjection a b)
-> Walk Filter x x
forall a b x.
Maybe (AsLabel a)
-> Greskell (LabeledP a)
-> Maybe (ByProjection a b)
-> Walk Filter x x
gWherePGeneric (AsLabel a -> Maybe (AsLabel a)
forall a. a -> Maybe a
Just AsLabel a
start) Greskell (LabeledP a)
p Maybe (ByProjection a b)
mby

-- Developer note: the @.where@ step with a traversal argument is not
-- implemented yet, because @.match@ basically covers the same
-- capability. If we are to implement it, consider the following.
--
-- - The @.where@ step with a traversal argument doesn't take @.by@
--   modulation.
--
-- - The traversal argument is a logic tree (zero or more combination
--   of @__.and()@, @__.or()@ and @__.not()@ methods) of filtering
--   traversals.
--
-- - If a filtering traversal starts with @__.as()@ step,
--   it has a special meaning. The @__.as()@ step works just like
--   @__.select()@, fetching a value specified by the label from the
--   path history. In this case, the input value passed to the
--   @.where@ step is discarded.
--
-- - If a filtering traversal ends with @.as()@ step, it works like a
--   predicate step. If fetches a value specified by the label from
--   the path history, and checks if it's equal to the input
--   value. This behavior is like the one in @.match@ step, but
--   without variable binding.
--
-- - If a filtering traversal doesn't have @.as()@ step at the
--   beginning or end, it works just like it's in @.filter@ step.


-- | Result of @.match@ step.
--
-- @since 1.2.0.0
data MatchResult

-- | A pattern for @.match@ step.
--
-- @since 1.2.0.0
data MatchPattern where
  -- | A pattern with the starting @.as@ label followed by traversal steps.
  MatchPattern :: AsLabel a -> Walk Transform a b -> MatchPattern

-- | Make a 'GTraversal' from the 'MatchPattern'. This function is
-- unsafe because it discards the types of input and output
-- traversers.
unsafePatternT :: MatchPattern -> GTraversal Transform () ()
unsafePatternT :: MatchPattern -> GTraversal Transform () ()
unsafePatternT (MatchPattern AsLabel a
l Walk Transform a b
w) = GTraversal Transform () b -> GTraversal Transform () ()
forall (g :: * -> * -> * -> *) c s e1 e2.
(ToGTraversal g, WalkType c) =>
g c s e1 -> g c s e2
unsafeCastEnd (GTraversal Transform () b -> GTraversal Transform () ())
-> GTraversal Transform () b -> GTraversal Transform () ()
forall a b. (a -> b) -> a -> b
$ GTraversal Transform a b -> GTraversal Transform () b
forall (g :: * -> * -> * -> *) c s1 e s2.
(ToGTraversal g, WalkType c) =>
g c s1 e -> g c s2 e
unsafeCastStart (GTraversal Transform a b -> GTraversal Transform () b)
-> GTraversal Transform a b -> GTraversal Transform () b
forall a b. (a -> b) -> a -> b
$ Walk Transform a b -> GTraversal Transform a b
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> GTraversal c s e
toGTraversal (AsLabel a -> Walk Transform a a
forall a. AsLabel a -> Walk Transform a a
gAs AsLabel a
l Walk Transform a a -> Walk Transform a b -> Walk Transform a b
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Walk Transform a b
w)

-- | A convenient function to make a 'MatchPattern' wrapped by
-- 'Logic.Leaf'.
--
-- @since 1.2.0.0
mPattern :: (WalkType c, Lift c Transform) => AsLabel a -> Walk c a b -> Logic MatchPattern
mPattern :: AsLabel a -> Walk c a b -> Logic MatchPattern
mPattern AsLabel a
l Walk c a b
w = MatchPattern -> Logic MatchPattern
forall a. a -> Logic a
Logic.Leaf (MatchPattern -> Logic MatchPattern)
-> MatchPattern -> Logic MatchPattern
forall a b. (a -> b) -> a -> b
$ AsLabel a -> Walk Transform a b -> MatchPattern
forall e b. AsLabel e -> Walk Transform e b -> MatchPattern
MatchPattern AsLabel a
l (Walk c a b -> Walk Transform a b
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk Walk c a b
w)

-- | @.match@ step.
--
-- If the top-level 'Logic' of the argument is 'Logic.And', the
-- patterns are directly passed to the @.match@ step arguments.
--
-- The result of @.match@ step, 'MatchResult', is an opaque
-- type. Basically you should not use it. Instead, you should use
-- 'gSelectN' etc to access the path history labels inside the
-- 'MatchPattern'.
--
-- See also: https://groups.google.com/g/gremlin-users/c/HVtldzV0Xk8
--
-- >>> :{
--  let
--    label_a = ("a" :: AsLabel AVertex)
--    label_b = "b"
--    key_age = ("age" :: Key AVertex Int)
--    patterns = Logic.And
--               ( mPattern label_a (gOut' [] >>> gAs label_b) )
--               [ mPattern label_b (gHas2' key_age 25)
--               ]
--  in toGremlin (source "g" & sV' [] &. gMatch patterns &. gSelectN label_a label_b [])
-- :}
-- "g.V().match(__.as(\"a\").out().as(\"b\"),__.as(\"b\").has(\"age\",25)).select(\"a\",\"b\")"
--
-- @since 1.2.0.0
gMatch :: Logic MatchPattern -> Walk Transform a MatchResult
gMatch :: Logic MatchPattern -> Walk Transform a MatchResult
gMatch Logic MatchPattern
patterns = Text -> [Text] -> Walk Transform a MatchResult
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"match" [Text]
args
  where
    args :: [Text]
args =
      case Logic MatchPattern
patterns of
        Logic.And Logic MatchPattern
p [Logic MatchPattern]
rest -> (Logic MatchPattern -> Text) -> [Logic MatchPattern] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (GTraversal Transform () () -> Text
forall a. ToGreskell a => a -> Text
toGremlin (GTraversal Transform () () -> Text)
-> (Logic MatchPattern -> GTraversal Transform () ())
-> Logic MatchPattern
-> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Logic MatchPattern -> GTraversal Transform () ()
toTraversal) (Logic MatchPattern
p Logic MatchPattern -> [Logic MatchPattern] -> [Logic MatchPattern]
forall a. a -> [a] -> [a]
: [Logic MatchPattern]
rest)
        Logic MatchPattern
_ -> [GTraversal Transform () () -> Text
forall a. ToGreskell a => a -> Text
toGremlin (GTraversal Transform () () -> Text)
-> GTraversal Transform () () -> Text
forall a b. (a -> b) -> a -> b
$ Logic MatchPattern -> GTraversal Transform () ()
toTraversal Logic MatchPattern
patterns]
    toTraversal :: Logic MatchPattern -> GTraversal Transform () ()
toTraversal Logic MatchPattern
l =
      case Logic MatchPattern
l of
        Logic.Leaf MatchPattern
p -> MatchPattern -> GTraversal Transform () ()
unsafePatternT MatchPattern
p
        Logic.And Logic MatchPattern
p [Logic MatchPattern]
rest -> Walk Transform () () -> GTraversal Transform () ()
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> GTraversal c s e
toGTraversal (Walk Transform () () -> GTraversal Transform () ())
-> Walk Transform () () -> GTraversal Transform () ()
forall a b. (a -> b) -> a -> b
$ [GTraversal Transform () ()] -> Walk Transform () ()
forall (g :: * -> * -> * -> *) c p s e.
(ToGTraversal g, WalkType c, WalkType p, Split c p) =>
[g c s e] -> Walk p s s
gAnd ([GTraversal Transform () ()] -> Walk Transform () ())
-> [GTraversal Transform () ()] -> Walk Transform () ()
forall a b. (a -> b) -> a -> b
$ (Logic MatchPattern -> GTraversal Transform () ())
-> [Logic MatchPattern] -> [GTraversal Transform () ()]
forall a b. (a -> b) -> [a] -> [b]
map Logic MatchPattern -> GTraversal Transform () ()
toTraversal (Logic MatchPattern
p Logic MatchPattern -> [Logic MatchPattern] -> [Logic MatchPattern]
forall a. a -> [a] -> [a]
: [Logic MatchPattern]
rest)
        Logic.Or Logic MatchPattern
p [Logic MatchPattern]
rest -> Walk Transform () () -> GTraversal Transform () ()
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> GTraversal c s e
toGTraversal (Walk Transform () () -> GTraversal Transform () ())
-> Walk Transform () () -> GTraversal Transform () ()
forall a b. (a -> b) -> a -> b
$ [GTraversal Transform () ()] -> Walk Transform () ()
forall (g :: * -> * -> * -> *) c p s e.
(ToGTraversal g, WalkType c, WalkType p, Split c p) =>
[g c s e] -> Walk p s s
gOr ([GTraversal Transform () ()] -> Walk Transform () ())
-> [GTraversal Transform () ()] -> Walk Transform () ()
forall a b. (a -> b) -> a -> b
$ (Logic MatchPattern -> GTraversal Transform () ())
-> [Logic MatchPattern] -> [GTraversal Transform () ()]
forall a b. (a -> b) -> [a] -> [b]
map Logic MatchPattern -> GTraversal Transform () ()
toTraversal (Logic MatchPattern
p Logic MatchPattern -> [Logic MatchPattern] -> [Logic MatchPattern]
forall a. a -> [a] -> [a]
: [Logic MatchPattern]
rest)
        Logic.Not Logic MatchPattern
p -> Walk Transform () () -> GTraversal Transform () ()
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> GTraversal c s e
toGTraversal (Walk Transform () () -> GTraversal Transform () ())
-> Walk Transform () () -> GTraversal Transform () ()
forall a b. (a -> b) -> a -> b
$ GTraversal Transform () () -> Walk Transform () ()
forall (g :: * -> * -> * -> *) c p s e.
(ToGTraversal g, WalkType c, WalkType p, Split c p) =>
g c s e -> Walk p s s
gNot (GTraversal Transform () () -> Walk Transform () ())
-> GTraversal Transform () () -> Walk Transform () ()
forall a b. (a -> b) -> a -> b
$ Logic MatchPattern -> GTraversal Transform () ()
toTraversal Logic MatchPattern
p

-- | @.is@ step of simple equality.
--
-- >>> toGremlin (source "g" & sV' [] &. gValues ["age" :: Key AVertex Int] &. gIs 30)
-- "g.V().values(\"age\").is(30)"
--
-- @since 1.0.1.0
gIs :: (WalkType c) => Greskell v -> Walk c v v
gIs :: Greskell v -> Walk c v v
gIs = Walk Filter v v -> Walk c v v
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter v v -> Walk c v v)
-> (Greskell v -> Walk Filter v v) -> Greskell v -> Walk c v v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Greskell v -> Walk Filter v v
forall v. Greskell v -> Walk Filter v v
gIs'

-- | Monomorphic version of 'gIs'.
--
-- @since 1.0.1.0
gIs' :: Greskell v -> Walk Filter v v
gIs' :: Greskell v -> Walk Filter v v
gIs' Greskell v
v = Text -> [Text] -> Walk Filter v v
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"is" [Greskell v -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell v
v]

-- | @.is@ step with predicate 'P'.
--
-- >>> toGremlin (source "g" & sV' [] &. gValues ["age" :: Key AVertex Int] &. gIsP (pLte 30))
-- "g.V().values(\"age\").is(P.lte(30))"
--
-- @since 1.0.1.0
gIsP :: (WalkType c) => Greskell (P v) -> Walk c v v
gIsP :: Greskell (P v) -> Walk c v v
gIsP = Walk Filter v v -> Walk c v v
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter v v -> Walk c v v)
-> (Greskell (P v) -> Walk Filter v v)
-> Greskell (P v)
-> Walk c v v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Greskell (P v) -> Walk Filter v v
forall v. Greskell (P v) -> Walk Filter v v
gIsP'

-- | Monomorphic version of 'gIsP'.
--
-- @since 1.0.1.0
gIsP' :: Greskell (P v) -> Walk Filter v v
gIsP' :: Greskell (P v) -> Walk Filter v v
gIsP' Greskell (P v)
p = Text -> [Text] -> Walk Filter v v
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"is" [Greskell (P v) -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell (P v)
p]

-- | @.has@ step with one argument.
--
-- >>> toGremlin (source "g" & sV' [] &. gHas1 "age")
-- "g.V().has(\"age\")"
gHas1 :: (WalkType c, Element s)
      => Key s v -- ^ property key
      -> Walk c s s
gHas1 :: Key s v -> Walk c s s
gHas1 = Walk Filter s s -> Walk c s s
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter s s -> Walk c s s)
-> (Key s v -> Walk Filter s s) -> Key s v -> Walk c s s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key s v -> Walk Filter s s
forall s v. Element s => Key s v -> Walk Filter s s
gHas1'

-- | Monomorphic version of 'gHas1'.
gHas1' :: (Element s) => Key s v -> Walk Filter s s
gHas1' :: Key s v -> Walk Filter s s
gHas1' Key s v
key = Text -> [Text] -> Walk Filter s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"has" [Key s v -> Text
forall a. ToGreskell a => a -> Text
toGremlin Key s v
key]

-- | @.has@ step with two arguments.
--
-- >>> toGremlin (source "g" & sV' [] &. gHas2 "age" (31 :: Greskell Int))
-- "g.V().has(\"age\",31)"
gHas2 :: (WalkType c, Element s) => Key s v -> Greskell v -> Walk c s s
gHas2 :: Key s v -> Greskell v -> Walk c s s
gHas2 Key s v
k Greskell v
v = Walk Filter s s -> Walk c s s
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter s s -> Walk c s s) -> Walk Filter s s -> Walk c s s
forall a b. (a -> b) -> a -> b
$ Key s v -> Greskell v -> Walk Filter s s
forall s v. Element s => Key s v -> Greskell v -> Walk Filter s s
gHas2' Key s v
k Greskell v
v

-- | Monomorphic verson of 'gHas2'.
gHas2' :: (Element s) => Key s v -> Greskell v -> Walk Filter s s
gHas2' :: Key s v -> Greskell v -> Walk Filter s s
gHas2' Key s v
k Greskell v
v = Text -> [Text] -> Walk Filter s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"has" [Key s v -> Text
forall a. ToGreskell a => a -> Text
toGremlin Key s v
k, Greskell v -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell v
v]

-- | @.has@ step with two arguments and 'P' type.
--
-- >>> toGremlin (source "g" & sV' [] &. gHas2P "age" (pBetween (30 :: Greskell Int) 40))
-- "g.V().has(\"age\",P.between(30,40))"
gHas2P :: (WalkType c, Element s)
       => Key s v -- ^ property key
       -> Greskell (P v) -- ^ predicate on the property value
       -> Walk c s s
gHas2P :: Key s v -> Greskell (P v) -> Walk c s s
gHas2P Key s v
k Greskell (P v)
p = Walk Filter s s -> Walk c s s
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter s s -> Walk c s s) -> Walk Filter s s -> Walk c s s
forall a b. (a -> b) -> a -> b
$ Key s v -> Greskell (P v) -> Walk Filter s s
forall s v.
Element s =>
Key s v -> Greskell (P v) -> Walk Filter s s
gHas2P' Key s v
k Greskell (P v)
p

-- | Monomorphic version of 'gHas2P'.
gHas2P' :: (Element s) => Key s v -> Greskell (P v) -> Walk Filter s s
gHas2P' :: Key s v -> Greskell (P v) -> Walk Filter s s
gHas2P' Key s v
key Greskell (P v)
p = Text -> [Text] -> Walk Filter s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"has" [Key s v -> Text
forall a. ToGreskell a => a -> Text
toGremlin Key s v
key, Greskell (P v) -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell (P v)
p]

-- TODO: has(Key,Traversal), has(Label,Key,P)

-- | @.hasLabel@ step.
--
-- >>> toGremlin (source "g" & sV' [] &. gHasLabel "person")
-- "g.V().hasLabel(\"person\")"
gHasLabel :: (Element s, WalkType c) => Greskell Text -> Walk c s s
gHasLabel :: Greskell Text -> Walk c s s
gHasLabel = Walk Filter s s -> Walk c s s
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter s s -> Walk c s s)
-> (Greskell Text -> Walk Filter s s)
-> Greskell Text
-> Walk c s s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Greskell Text -> Walk Filter s s
forall s. Element s => Greskell Text -> Walk Filter s s
gHasLabel'

-- | Monomorphic version of 'gHasLabel'.
gHasLabel' :: (Element s) => Greskell Text -> Walk Filter s s
gHasLabel' :: Greskell Text -> Walk Filter s s
gHasLabel' Greskell Text
l = Text -> [Text] -> Walk Filter s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"hasLabel" [Greskell Text -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell Text
l]

-- | @.hasLabel@ step with 'P' type. Supported since TinkerPop 3.2.7.
--
-- >>> toGremlin (source "g" & sV' [] &. gHasLabelP (pEq "person"))
-- "g.V().hasLabel(P.eq(\"person\"))"
gHasLabelP :: (Element s, WalkType c)
           => Greskell (P Text) -- ^ predicate on Element label.
           -> Walk c s s
gHasLabelP :: Greskell (P Text) -> Walk c s s
gHasLabelP = Walk Filter s s -> Walk c s s
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter s s -> Walk c s s)
-> (Greskell (P Text) -> Walk Filter s s)
-> Greskell (P Text)
-> Walk c s s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Greskell (P Text) -> Walk Filter s s
forall s. Element s => Greskell (P Text) -> Walk Filter s s
gHasLabelP'

-- | Monomorphic version of 'gHasLabelP'.
gHasLabelP' :: Element s
            => Greskell (P Text)
            -> Walk Filter s s
gHasLabelP' :: Greskell (P Text) -> Walk Filter s s
gHasLabelP' Greskell (P Text)
p = Text -> [Text] -> Walk Filter s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"hasLabel" [Greskell (P Text) -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell (P Text)
p]

-- | @.hasId@ step.
--
-- >>> toGremlin (source "g" & sV' [] &. gHasId (fmap ElementID $ gvalueInt $ (7 :: Int)))
-- "g.V().hasId(7)"
gHasId :: (Element s, WalkType c) => Greskell (ElementID s) -> Walk c s s
gHasId :: Greskell (ElementID s) -> Walk c s s
gHasId = Walk Filter s s -> Walk c s s
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter s s -> Walk c s s)
-> (Greskell (ElementID s) -> Walk Filter s s)
-> Greskell (ElementID s)
-> Walk c s s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Greskell (ElementID s) -> Walk Filter s s
forall s. Element s => Greskell (ElementID s) -> Walk Filter s s
gHasId'

-- | Monomorphic version of 'gHasId'.
gHasId' :: Element s => Greskell (ElementID s) -> Walk Filter s s
gHasId' :: Greskell (ElementID s) -> Walk Filter s s
gHasId' Greskell (ElementID s)
i = Text -> [Text] -> Walk Filter s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"hasId" [Greskell (ElementID s) -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell (ElementID s)
i]

-- | @.hasId@ step with 'P' type. Supported since TinkerPop 3.2.7.
--
-- >>> toGremlin (source "g" & sV' [] &. gHasIdP (pLte $ fmap ElementID $ gvalueInt (100 :: Int)))
-- "g.V().hasId(P.lte(100))"
gHasIdP :: (Element s, WalkType c)
        => Greskell (P (ElementID s))
        -> Walk c s s
gHasIdP :: Greskell (P (ElementID s)) -> Walk c s s
gHasIdP = Walk Filter s s -> Walk c s s
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter s s -> Walk c s s)
-> (Greskell (P (ElementID s)) -> Walk Filter s s)
-> Greskell (P (ElementID s))
-> Walk c s s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Greskell (P (ElementID s)) -> Walk Filter s s
forall s.
Element s =>
Greskell (P (ElementID s)) -> Walk Filter s s
gHasIdP'

-- | Monomorphic version of 'gHasIdP'.
gHasIdP' :: Element s
         => Greskell (P (ElementID s))
         -> Walk Filter s s
gHasIdP' :: Greskell (P (ElementID s)) -> Walk Filter s s
gHasIdP' Greskell (P (ElementID s))
p = Text -> [Text] -> Walk Filter s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"hasId" [Greskell (P (ElementID s)) -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell (P (ElementID s))
p]

-- | @.hasKey@ step. The input type should be a VertexProperty.
--
-- >>> toGremlin (source "g" & sV' [] &. gProperties [] &. gHasKey "age")
-- "g.V().properties().hasKey(\"age\")"
gHasKey :: (Element (p v), Property p, WalkType c) => Greskell Text -> Walk c (p v) (p v)
gHasKey :: Greskell Text -> Walk c (p v) (p v)
gHasKey = Walk Filter (p v) (p v) -> Walk c (p v) (p v)
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter (p v) (p v) -> Walk c (p v) (p v))
-> (Greskell Text -> Walk Filter (p v) (p v))
-> Greskell Text
-> Walk c (p v) (p v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Greskell Text -> Walk Filter (p v) (p v)
forall (p :: * -> *) v.
(Element (p v), Property p) =>
Greskell Text -> Walk Filter (p v) (p v)
gHasKey'

-- | Monomorphic version of 'gHasKey'.
gHasKey' :: (Element (p v), Property p) => Greskell Text -> Walk Filter (p v) (p v)
gHasKey' :: Greskell Text -> Walk Filter (p v) (p v)
gHasKey' Greskell Text
k = Text -> [Text] -> Walk Filter (p v) (p v)
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"hasKey" [Greskell Text -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell Text
k]

-- | @.hasKey@ step with 'P' type. Supported since TinkerPop 3.2.7.
gHasKeyP :: (Element (p v), Property p, WalkType c)
         => Greskell (P Text) -- ^ predicate on the VertexProperty's key.
         -> Walk c (p v) (p v)
gHasKeyP :: Greskell (P Text) -> Walk c (p v) (p v)
gHasKeyP = Walk Filter (p v) (p v) -> Walk c (p v) (p v)
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter (p v) (p v) -> Walk c (p v) (p v))
-> (Greskell (P Text) -> Walk Filter (p v) (p v))
-> Greskell (P Text)
-> Walk c (p v) (p v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Greskell (P Text) -> Walk Filter (p v) (p v)
forall (p :: * -> *) v.
(Element (p v), Property p) =>
Greskell (P Text) -> Walk Filter (p v) (p v)
gHasKeyP'

-- | Monomorphic version of 'gHasKeyP'.
gHasKeyP' :: (Element (p v), Property p) => Greskell (P Text) -> Walk Filter (p v) (p v)
gHasKeyP' :: Greskell (P Text) -> Walk Filter (p v) (p v)
gHasKeyP' Greskell (P Text)
p = Text -> [Text] -> Walk Filter (p v) (p v)
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"hasKey" [Greskell (P Text) -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell (P Text)
p]

-- | @.hasValue@ step. The input type should be a VertexProperty.
--
-- >>> toGremlin (source "g" & sV' [] &. gProperties ["age"] &. gHasValue (32 :: Greskell Int))
-- "g.V().properties(\"age\").hasValue(32)"
gHasValue :: (Element (p v), Property p, WalkType c) => Greskell v -> Walk c (p v) (p v)
gHasValue :: Greskell v -> Walk c (p v) (p v)
gHasValue = Walk Filter (p v) (p v) -> Walk c (p v) (p v)
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter (p v) (p v) -> Walk c (p v) (p v))
-> (Greskell v -> Walk Filter (p v) (p v))
-> Greskell v
-> Walk c (p v) (p v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Greskell v -> Walk Filter (p v) (p v)
forall (p :: * -> *) v.
(Element (p v), Property p) =>
Greskell v -> Walk Filter (p v) (p v)
gHasValue'

-- | Monomorphic version of 'gHasValue'.
gHasValue' :: (Element (p v), Property p) => Greskell v -> Walk Filter (p v) (p v)
gHasValue' :: Greskell v -> Walk Filter (p v) (p v)
gHasValue' Greskell v
v = Text -> [Text] -> Walk Filter (p v) (p v)
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"hasValue" [Greskell v -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell v
v]

-- | @.hasValue@ step with 'P' type. Supported since TinkerPop 3.2.7.
--
-- >>> toGremlin (source "g" & sV' [] &. gProperties ["age"] &. gHasValueP (pBetween (30 :: Greskell Int) 40))
-- "g.V().properties(\"age\").hasValue(P.between(30,40))"
gHasValueP :: (Element (p v), Property p, WalkType c)
           => Greskell (P v) -- ^ predicate on the VertexProperty's value
           -> Walk c (p v) (p v)
gHasValueP :: Greskell (P v) -> Walk c (p v) (p v)
gHasValueP = Walk Filter (p v) (p v) -> Walk c (p v) (p v)
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (Walk Filter (p v) (p v) -> Walk c (p v) (p v))
-> (Greskell (P v) -> Walk Filter (p v) (p v))
-> Greskell (P v)
-> Walk c (p v) (p v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Greskell (P v) -> Walk Filter (p v) (p v)
forall (p :: * -> *) v.
(Element (p v), Property p) =>
Greskell (P v) -> Walk Filter (p v) (p v)
gHasValueP'

-- | Monomorphic version of 'gHasValueP'.
gHasValueP' :: (Element (p v), Property p) => Greskell (P v) -> Walk Filter (p v) (p v)
gHasValueP' :: Greskell (P v) -> Walk Filter (p v) (p v)
gHasValueP' Greskell (P v)
p = Text -> [Text] -> Walk Filter (p v) (p v)
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"hasValue" [Greskell (P v) -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell (P v)
p]

multiLogic :: (ToGTraversal g, WalkType c, WalkType p, Split c p)
           => Text -- ^ method name
           -> [g c s e]
           -> Walk p s s
multiLogic :: Text -> [g c s e] -> Walk p s s
multiLogic Text
method_name = Text -> [Text] -> Walk p s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
method_name ([Text] -> Walk p s s)
-> ([g c s e] -> [Text]) -> [g c s e] -> Walk p s s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (g c s e -> Text) -> [g c s e] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map g c s e -> Text
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> Text
travToG

-- | @.and@ step.
--
-- >>> toGremlin (source "g" & sV' [] &. gAnd [gOut' ["knows"], gHas1 "age"])
-- "g.V().and(__.out(\"knows\"),__.has(\"age\"))"
gAnd :: (ToGTraversal g, WalkType c, WalkType p, Split c p) => [g c s e] -> Walk p s s
gAnd :: [g c s e] -> Walk p s s
gAnd = Text -> [g c s e] -> Walk p s s
forall (g :: * -> * -> * -> *) c p s e.
(ToGTraversal g, WalkType c, WalkType p, Split c p) =>
Text -> [g c s e] -> Walk p s s
multiLogic Text
"and"

-- | @.or@ step.
--
-- >>> toGremlin (source "g" & sV' [] &. gOr [gOut' ["knows"], gHas1 "age"])
-- "g.V().or(__.out(\"knows\"),__.has(\"age\"))"
gOr :: (ToGTraversal g, WalkType c, WalkType p, Split c p) => [g c s e] -> Walk p s s
gOr :: [g c s e] -> Walk p s s
gOr = Text -> [g c s e] -> Walk p s s
forall (g :: * -> * -> * -> *) c p s e.
(ToGTraversal g, WalkType c, WalkType p, Split c p) =>
Text -> [g c s e] -> Walk p s s
multiLogic Text
"or"

-- | @.not@ step.
--
-- >>> toGremlin (source "g" & sV' [] &. gNot (gOut' ["knows"]))
-- "g.V().not(__.out(\"knows\"))"
gNot :: (ToGTraversal g, WalkType c, WalkType p, Split c p) => g c s e -> Walk p s s
gNot :: g c s e -> Walk p s s
gNot g c s e
cond = Text -> [Text] -> Walk p s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"not" [g c s e -> Text
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> Text
travToG g c s e
cond]

-- | @.range@ step. This step is not a 'Filter', because the filtering
-- decision by this step is based on position of each element, not the
-- element itself. This violates 'Filter' law.
--
-- >>> toGremlin (source "g" & sV' [] &. gRange 0 100)
-- "g.V().range(0,100)"
gRange :: Greskell Int
       -- ^ min
       -> Greskell Int
       -- ^ max
       -> Walk Transform s s
gRange :: Greskell Int -> Greskell Int -> Walk Transform s s
gRange Greskell Int
min_g Greskell Int
max_g = Text -> [Text] -> Walk Transform s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"range" ([Text] -> Walk Transform s s) -> [Text] -> Walk Transform s s
forall a b. (a -> b) -> a -> b
$ (Greskell Int -> Text) -> [Greskell Int] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Greskell Int -> Text
forall a. ToGreskell a => a -> Text
toGremlin [Greskell Int
min_g, Greskell Int
max_g]

-- | @.limit@ step.
--
-- @since 0.2.1.0
gLimit :: Greskell Int -> Walk Transform s s
gLimit :: Greskell Int -> Walk Transform s s
gLimit Greskell Int
num = Text -> [Text] -> Walk Transform s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"limit" [Greskell Int -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell Int
num]

-- | @.tail@ step.
--
-- @since 0.2.1.0
gTail :: Greskell Int -> Walk Transform s s
gTail :: Greskell Int -> Walk Transform s s
gTail Greskell Int
num = Text -> [Text] -> Walk Transform s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"tail" [Greskell Int -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell Int
num]

-- | @.skip@ step.
--
-- @since 0.2.1.0
gSkip :: Greskell Int -> Walk Transform s s
gSkip :: Greskell Int -> Walk Transform s s
gSkip Greskell Int
num = Text -> [Text] -> Walk Transform s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"skip" [Greskell Int -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell Int
num]

-- | A label that points to a loop created by @.repeat@ step. It can
-- be used by @.loops@ step to specify the loop.
--
-- @since 1.0.1.0
newtype RepeatLabel =
  RepeatLabel { RepeatLabel -> Text
unRepeatLabel :: Text }
  deriving (Int -> RepeatLabel -> ShowS
[RepeatLabel] -> ShowS
RepeatLabel -> String
(Int -> RepeatLabel -> ShowS)
-> (RepeatLabel -> String)
-> ([RepeatLabel] -> ShowS)
-> Show RepeatLabel
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RepeatLabel] -> ShowS
$cshowList :: [RepeatLabel] -> ShowS
show :: RepeatLabel -> String
$cshow :: RepeatLabel -> String
showsPrec :: Int -> RepeatLabel -> ShowS
$cshowsPrec :: Int -> RepeatLabel -> ShowS
Show,RepeatLabel -> RepeatLabel -> Bool
(RepeatLabel -> RepeatLabel -> Bool)
-> (RepeatLabel -> RepeatLabel -> Bool) -> Eq RepeatLabel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RepeatLabel -> RepeatLabel -> Bool
$c/= :: RepeatLabel -> RepeatLabel -> Bool
== :: RepeatLabel -> RepeatLabel -> Bool
$c== :: RepeatLabel -> RepeatLabel -> Bool
Eq,Eq RepeatLabel
Eq RepeatLabel
-> (RepeatLabel -> RepeatLabel -> Ordering)
-> (RepeatLabel -> RepeatLabel -> Bool)
-> (RepeatLabel -> RepeatLabel -> Bool)
-> (RepeatLabel -> RepeatLabel -> Bool)
-> (RepeatLabel -> RepeatLabel -> Bool)
-> (RepeatLabel -> RepeatLabel -> RepeatLabel)
-> (RepeatLabel -> RepeatLabel -> RepeatLabel)
-> Ord RepeatLabel
RepeatLabel -> RepeatLabel -> Bool
RepeatLabel -> RepeatLabel -> Ordering
RepeatLabel -> RepeatLabel -> RepeatLabel
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: RepeatLabel -> RepeatLabel -> RepeatLabel
$cmin :: RepeatLabel -> RepeatLabel -> RepeatLabel
max :: RepeatLabel -> RepeatLabel -> RepeatLabel
$cmax :: RepeatLabel -> RepeatLabel -> RepeatLabel
>= :: RepeatLabel -> RepeatLabel -> Bool
$c>= :: RepeatLabel -> RepeatLabel -> Bool
> :: RepeatLabel -> RepeatLabel -> Bool
$c> :: RepeatLabel -> RepeatLabel -> Bool
<= :: RepeatLabel -> RepeatLabel -> Bool
$c<= :: RepeatLabel -> RepeatLabel -> Bool
< :: RepeatLabel -> RepeatLabel -> Bool
$c< :: RepeatLabel -> RepeatLabel -> Bool
compare :: RepeatLabel -> RepeatLabel -> Ordering
$ccompare :: RepeatLabel -> RepeatLabel -> Ordering
$cp1Ord :: Eq RepeatLabel
Ord,String -> RepeatLabel
(String -> RepeatLabel) -> IsString RepeatLabel
forall a. (String -> a) -> IsString a
fromString :: String -> RepeatLabel
$cfromString :: String -> RepeatLabel
IsString)

-- | Return Gremlin String literal.
instance ToGreskell RepeatLabel where
  type GreskellReturn RepeatLabel = Text
  toGreskell :: RepeatLabel -> Greskell (GreskellReturn RepeatLabel)
toGreskell (RepeatLabel Text
t) = Text -> Greskell Text
Greskell.string Text
t

-- | Position of a step modulator relative to @.repeat@ step.
--
-- @since 1.0.1.0
data RepeatPos = RepeatHead -- ^ Modulator before the @.repeat@ step.
               | RepeatTail -- ^ Modulator after the @.repeat@ step.
               deriving (Int -> RepeatPos -> ShowS
[RepeatPos] -> ShowS
RepeatPos -> String
(Int -> RepeatPos -> ShowS)
-> (RepeatPos -> String)
-> ([RepeatPos] -> ShowS)
-> Show RepeatPos
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RepeatPos] -> ShowS
$cshowList :: [RepeatPos] -> ShowS
show :: RepeatPos -> String
$cshow :: RepeatPos -> String
showsPrec :: Int -> RepeatPos -> ShowS
$cshowsPrec :: Int -> RepeatPos -> ShowS
Show,RepeatPos -> RepeatPos -> Bool
(RepeatPos -> RepeatPos -> Bool)
-> (RepeatPos -> RepeatPos -> Bool) -> Eq RepeatPos
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RepeatPos -> RepeatPos -> Bool
$c/= :: RepeatPos -> RepeatPos -> Bool
== :: RepeatPos -> RepeatPos -> Bool
$c== :: RepeatPos -> RepeatPos -> Bool
Eq,Eq RepeatPos
Eq RepeatPos
-> (RepeatPos -> RepeatPos -> Ordering)
-> (RepeatPos -> RepeatPos -> Bool)
-> (RepeatPos -> RepeatPos -> Bool)
-> (RepeatPos -> RepeatPos -> Bool)
-> (RepeatPos -> RepeatPos -> Bool)
-> (RepeatPos -> RepeatPos -> RepeatPos)
-> (RepeatPos -> RepeatPos -> RepeatPos)
-> Ord RepeatPos
RepeatPos -> RepeatPos -> Bool
RepeatPos -> RepeatPos -> Ordering
RepeatPos -> RepeatPos -> RepeatPos
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: RepeatPos -> RepeatPos -> RepeatPos
$cmin :: RepeatPos -> RepeatPos -> RepeatPos
max :: RepeatPos -> RepeatPos -> RepeatPos
$cmax :: RepeatPos -> RepeatPos -> RepeatPos
>= :: RepeatPos -> RepeatPos -> Bool
$c>= :: RepeatPos -> RepeatPos -> Bool
> :: RepeatPos -> RepeatPos -> Bool
$c> :: RepeatPos -> RepeatPos -> Bool
<= :: RepeatPos -> RepeatPos -> Bool
$c<= :: RepeatPos -> RepeatPos -> Bool
< :: RepeatPos -> RepeatPos -> Bool
$c< :: RepeatPos -> RepeatPos -> Bool
compare :: RepeatPos -> RepeatPos -> Ordering
$ccompare :: RepeatPos -> RepeatPos -> Ordering
$cp1Ord :: Eq RepeatPos
Ord,Int -> RepeatPos
RepeatPos -> Int
RepeatPos -> [RepeatPos]
RepeatPos -> RepeatPos
RepeatPos -> RepeatPos -> [RepeatPos]
RepeatPos -> RepeatPos -> RepeatPos -> [RepeatPos]
(RepeatPos -> RepeatPos)
-> (RepeatPos -> RepeatPos)
-> (Int -> RepeatPos)
-> (RepeatPos -> Int)
-> (RepeatPos -> [RepeatPos])
-> (RepeatPos -> RepeatPos -> [RepeatPos])
-> (RepeatPos -> RepeatPos -> [RepeatPos])
-> (RepeatPos -> RepeatPos -> RepeatPos -> [RepeatPos])
-> Enum RepeatPos
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: RepeatPos -> RepeatPos -> RepeatPos -> [RepeatPos]
$cenumFromThenTo :: RepeatPos -> RepeatPos -> RepeatPos -> [RepeatPos]
enumFromTo :: RepeatPos -> RepeatPos -> [RepeatPos]
$cenumFromTo :: RepeatPos -> RepeatPos -> [RepeatPos]
enumFromThen :: RepeatPos -> RepeatPos -> [RepeatPos]
$cenumFromThen :: RepeatPos -> RepeatPos -> [RepeatPos]
enumFrom :: RepeatPos -> [RepeatPos]
$cenumFrom :: RepeatPos -> [RepeatPos]
fromEnum :: RepeatPos -> Int
$cfromEnum :: RepeatPos -> Int
toEnum :: Int -> RepeatPos
$ctoEnum :: Int -> RepeatPos
pred :: RepeatPos -> RepeatPos
$cpred :: RepeatPos -> RepeatPos
succ :: RepeatPos -> RepeatPos
$csucc :: RepeatPos -> RepeatPos
Enum,RepeatPos
RepeatPos -> RepeatPos -> Bounded RepeatPos
forall a. a -> a -> Bounded a
maxBound :: RepeatPos
$cmaxBound :: RepeatPos
minBound :: RepeatPos
$cminBound :: RepeatPos
Bounded)

-- | @.until@ or @.times@ modulator step.
--
-- Type @c@ is the 'WalkType' of the parent @.repeat@ step. Type @s@
-- is the start (and end) type of the @.repeat@ step.
--
-- @since 1.0.1.0
data RepeatUntil c s where
  -- | @.times@ modulator.
  RepeatTimes :: Greskell Int -> RepeatUntil c s
  -- | @.until@ modulator with a sub-traversal as the predicate to
  -- decide if the repetition should stop.
  RepeatUntilT :: (WalkType cc, WalkType c, Split cc c) => GTraversal cc s e -> RepeatUntil c s

deriving instance Show (RepeatUntil c s)

makeUntilWalk :: WalkType c => RepeatUntil c s -> Walk c s s
makeUntilWalk :: RepeatUntil c s -> Walk c s s
makeUntilWalk (RepeatTimes Greskell Int
count) = Text -> [Text] -> Walk c s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"times" [Greskell Int -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell Int
count]
makeUntilWalk (RepeatUntilT GTraversal cc s e
trav) = Text -> [Text] -> Walk c s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"until" [GTraversal cc s e -> Text
forall a. ToGreskell a => a -> Text
toGremlin GTraversal cc s e
trav]

-- | @.emit@ modulator step.
--
-- Type @c@ is the 'WalkType' of the parent @.repeat@ step. Type @s@
-- is the start (and end) type of the @.repeat@ step.
--
-- @since 1.0.1.0
data RepeatEmit c s where
  -- | @.emit@ modulator without argument. It always emits the input
  -- traverser of type @s@.
  RepeatEmit :: RepeatEmit c s
  -- | @.emit@ modulator with a sub-traversal as the predicate to
  -- decide if it emits the traverser.
  RepeatEmitT :: (WalkType cc, WalkType c, Split cc c) => GTraversal cc s e -> RepeatEmit c s

deriving instance Show (RepeatEmit c s)

makeEmitWalk :: WalkType c => RepeatEmit c s -> Walk c s s
makeEmitWalk :: RepeatEmit c s -> Walk c s s
makeEmitWalk (RepeatEmit c s
RepeatEmit) = Text -> [Text] -> Walk c s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"emit" []
makeEmitWalk (RepeatEmitT GTraversal cc s e
trav) = Text -> [Text] -> Walk c s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"emit" [GTraversal cc s e -> Text
forall a. ToGreskell a => a -> Text
toGremlin GTraversal cc s e
trav]



-- | Zero or more Gremlin steps.
--
-- @since 1.0.1.0
newtype MWalk c s e = MWalk (Maybe (Walk c s e))
                    deriving (Int -> MWalk c s e -> ShowS
[MWalk c s e] -> ShowS
MWalk c s e -> String
(Int -> MWalk c s e -> ShowS)
-> (MWalk c s e -> String)
-> ([MWalk c s e] -> ShowS)
-> Show (MWalk c s e)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall c s e. Int -> MWalk c s e -> ShowS
forall c s e. [MWalk c s e] -> ShowS
forall c s e. MWalk c s e -> String
showList :: [MWalk c s e] -> ShowS
$cshowList :: forall c s e. [MWalk c s e] -> ShowS
show :: MWalk c s e -> String
$cshow :: forall c s e. MWalk c s e -> String
showsPrec :: Int -> MWalk c s e -> ShowS
$cshowsPrec :: forall c s e. Int -> MWalk c s e -> ShowS
Show)

deriving instance WalkType c => Semigroup (MWalk c s s)
deriving instance WalkType c => Monoid (MWalk c s s)

toMWalk :: Walk c s e -> MWalk c s e
toMWalk :: Walk c s e -> MWalk c s e
toMWalk = Maybe (Walk c s e) -> MWalk c s e
forall c s e. Maybe (Walk c s e) -> MWalk c s e
MWalk (Maybe (Walk c s e) -> MWalk c s e)
-> (Walk c s e -> Maybe (Walk c s e)) -> Walk c s e -> MWalk c s e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Walk c s e -> Maybe (Walk c s e)
forall a. a -> Maybe a
Just

-- | @MWalk Nothing@ is coverted to identity step.
fromMWalk :: WalkType c => MWalk c s s -> Walk c s s
fromMWalk :: MWalk c s s -> Walk c s s
fromMWalk (MWalk Maybe (Walk c s s)
Nothing) = Walk c s s
forall a. Monoid a => a
mempty
fromMWalk (MWalk (Just Walk c s s
w)) = Walk c s s
w



-- | @.repeat@ step.
--
-- @since 1.0.1.0
gRepeat :: (ToGTraversal g, WalkType c)
        => Maybe RepeatLabel -- ^ Label for the loop.
        -> Maybe (RepeatPos, RepeatUntil c s)
        -- ^ @.until@ or @.times@ modulator. You can use 'gTimes',
        -- 'gUntilHead', 'gUntilTail' to make this argument.
        -> Maybe (RepeatPos, RepeatEmit c s)
        -- ^ @.emit@ modulator. You can use 'gEmitHead', 'gEmitTail',
        -- 'gEmitHeadT', 'gEmitTailT' to make this argument.
        -> g c s s -- ^ Repeated traversal
        -> Walk c s s
gRepeat :: Maybe RepeatLabel
-> Maybe (RepeatPos, RepeatUntil c s)
-> Maybe (RepeatPos, RepeatEmit c s)
-> g c s s
-> Walk c s s
gRepeat Maybe RepeatLabel
mlabel Maybe (RepeatPos, RepeatUntil c s)
muntil Maybe (RepeatPos, RepeatEmit c s)
memit g c s s
repeated_trav = MWalk c s s -> Walk c s s
forall c s. WalkType c => MWalk c s s -> Walk c s s
fromMWalk (MWalk c s s
head_walk MWalk c s s -> MWalk c s s -> MWalk c s s
forall a. Semigroup a => a -> a -> a
<> Walk c s s -> MWalk c s s
forall c s e. Walk c s e -> MWalk c s e
toMWalk Walk c s s
repeat_body MWalk c s s -> MWalk c s s -> MWalk c s s
forall a. Semigroup a => a -> a -> a
<> MWalk c s s
tail_walk)
  where
    repeat_body :: Walk c s s
repeat_body = Text -> [Text] -> Walk c s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"repeat" ([Text]
label_args [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [g c s s -> Text
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> Text
travToG g c s s
repeated_trav])
    label_args :: [Text]
label_args = [Text] -> (RepeatLabel -> [Text]) -> Maybe RepeatLabel -> [Text]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\RepeatLabel
l -> [RepeatLabel -> Text
forall a. ToGreskell a => a -> Text
toGremlin RepeatLabel
l]) Maybe RepeatLabel
mlabel
    head_walk :: MWalk c s s
head_walk = MWalk c s s
head_until MWalk c s s -> MWalk c s s -> MWalk c s s
forall a. Semigroup a => a -> a -> a
<> MWalk c s s
head_emit
    tail_walk :: MWalk c s s
tail_walk = MWalk c s s
tail_until MWalk c s s -> MWalk c s s -> MWalk c s s
forall a. Semigroup a => a -> a -> a
<> MWalk c s s
tail_emit
    (MWalk c s s
head_until, MWalk c s s
tail_until) =
      case Maybe (RepeatPos, RepeatUntil c s)
muntil of
        Maybe (RepeatPos, RepeatUntil c s)
Nothing -> (MWalk c s s
forall a. Monoid a => a
mempty, MWalk c s s
forall a. Monoid a => a
mempty)
        Just (RepeatPos
pos, RepeatUntil c s
u) ->
          case RepeatPos
pos of
            RepeatPos
RepeatHead -> (Walk c s s -> MWalk c s s
forall c s e. Walk c s e -> MWalk c s e
toMWalk (Walk c s s -> MWalk c s s) -> Walk c s s -> MWalk c s s
forall a b. (a -> b) -> a -> b
$ RepeatUntil c s -> Walk c s s
forall c s. WalkType c => RepeatUntil c s -> Walk c s s
makeUntilWalk RepeatUntil c s
u, MWalk c s s
forall a. Monoid a => a
mempty)
            RepeatPos
RepeatTail -> (MWalk c s s
forall a. Monoid a => a
mempty, Walk c s s -> MWalk c s s
forall c s e. Walk c s e -> MWalk c s e
toMWalk (Walk c s s -> MWalk c s s) -> Walk c s s -> MWalk c s s
forall a b. (a -> b) -> a -> b
$ RepeatUntil c s -> Walk c s s
forall c s. WalkType c => RepeatUntil c s -> Walk c s s
makeUntilWalk RepeatUntil c s
u)
    (MWalk c s s
head_emit, MWalk c s s
tail_emit) =
      case Maybe (RepeatPos, RepeatEmit c s)
memit of
        Maybe (RepeatPos, RepeatEmit c s)
Nothing -> (MWalk c s s
forall a. Monoid a => a
mempty, MWalk c s s
forall a. Monoid a => a
mempty)
        Just (RepeatPos
pos, RepeatEmit c s
e) ->
          case RepeatPos
pos of
            RepeatPos
RepeatHead -> (Walk c s s -> MWalk c s s
forall c s e. Walk c s e -> MWalk c s e
toMWalk (Walk c s s -> MWalk c s s) -> Walk c s s -> MWalk c s s
forall a b. (a -> b) -> a -> b
$ RepeatEmit c s -> Walk c s s
forall c s. WalkType c => RepeatEmit c s -> Walk c s s
makeEmitWalk RepeatEmit c s
e, MWalk c s s
forall a. Monoid a => a
mempty)
            RepeatPos
RepeatTail -> (MWalk c s s
forall a. Monoid a => a
mempty, Walk c s s -> MWalk c s s
forall c s e. Walk c s e -> MWalk c s e
toMWalk (Walk c s s -> MWalk c s s) -> Walk c s s -> MWalk c s s
forall a b. (a -> b) -> a -> b
$ RepeatEmit c s -> Walk c s s
forall c s. WalkType c => RepeatEmit c s -> Walk c s s
makeEmitWalk RepeatEmit c s
e)

-- | @.times@ modulator before the @.repeat@ step. It always returns
-- 'Just'.
--
-- >>> toGremlin (source "g" & sV' [] &. gRepeat Nothing (gTimes 3) Nothing (gOut' []))
-- "g.V().times(3).repeat(__.out())"
--
-- @since 1.0.1.0
gTimes :: Greskell Int
       -- ^ Repeat count. If it's less than or equal to 0, the
       -- repeated traversal is never executed.
       -> Maybe (RepeatPos, RepeatUntil c s)
gTimes :: Greskell Int -> Maybe (RepeatPos, RepeatUntil c s)
gTimes Greskell Int
c = (RepeatPos, RepeatUntil c s) -> Maybe (RepeatPos, RepeatUntil c s)
forall a. a -> Maybe a
Just (RepeatPos
RepeatHead, Greskell Int -> RepeatUntil c s
forall c s. Greskell Int -> RepeatUntil c s
RepeatTimes Greskell Int
c)

-- | @.until@ modulator before the @.repeat@ step. It always returns
-- 'Just'.
--
-- >>> toGremlin (source "g" & sV' [] &. gRepeat Nothing (gUntilHead $ gHasLabel' "person") Nothing (gOut' []))
-- "g.V().until(__.hasLabel(\"person\")).repeat(__.out())"
--
-- @since 1.0.1.0
gUntilHead :: (ToGTraversal g, WalkType c, WalkType cc, Split cc c) => g cc s e -> Maybe (RepeatPos, RepeatUntil c s)
gUntilHead :: g cc s e -> Maybe (RepeatPos, RepeatUntil c s)
gUntilHead g cc s e
trav = (RepeatPos, RepeatUntil c s) -> Maybe (RepeatPos, RepeatUntil c s)
forall a. a -> Maybe a
Just (RepeatPos
RepeatHead, GTraversal cc s e -> RepeatUntil c s
forall cc c s e.
(WalkType cc, WalkType c, Split cc c) =>
GTraversal cc s e -> RepeatUntil c s
RepeatUntilT (GTraversal cc s e -> RepeatUntil c s)
-> GTraversal cc s e -> RepeatUntil c s
forall a b. (a -> b) -> a -> b
$ g cc s e -> GTraversal cc s e
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> GTraversal c s e
toGTraversal g cc s e
trav)

-- | @.until@ modulator after the @.repeat@ step. It always returns
-- 'Just'.
--
-- >>> toGremlin (source "g" & sV' [] &. gRepeat Nothing (gUntilTail $ gHasLabel' "person") Nothing (gOut' []))
-- "g.V().repeat(__.out()).until(__.hasLabel(\"person\"))"
--
-- @since 1.0.1.0
gUntilTail :: (ToGTraversal g, WalkType c, WalkType cc, Split cc c) => g cc s e -> Maybe (RepeatPos, RepeatUntil c s)
gUntilTail :: g cc s e -> Maybe (RepeatPos, RepeatUntil c s)
gUntilTail g cc s e
trav = (RepeatPos, RepeatUntil c s) -> Maybe (RepeatPos, RepeatUntil c s)
forall a. a -> Maybe a
Just (RepeatPos
RepeatTail, GTraversal cc s e -> RepeatUntil c s
forall cc c s e.
(WalkType cc, WalkType c, Split cc c) =>
GTraversal cc s e -> RepeatUntil c s
RepeatUntilT (GTraversal cc s e -> RepeatUntil c s)
-> GTraversal cc s e -> RepeatUntil c s
forall a b. (a -> b) -> a -> b
$ g cc s e -> GTraversal cc s e
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> GTraversal c s e
toGTraversal g cc s e
trav)

-- | @.emit@ modulator without argument before the @.repeat@ step. It
-- always returns 'Just'.
--
-- >>> toGremlin (source "g" & sV' [] &. gRepeat Nothing Nothing gEmitHead (gOut' []))
-- "g.V().emit().repeat(__.out())"
--
-- @since 1.0.1.0
gEmitHead :: Maybe (RepeatPos, RepeatEmit c s)
gEmitHead :: Maybe (RepeatPos, RepeatEmit c s)
gEmitHead = (RepeatPos, RepeatEmit c s) -> Maybe (RepeatPos, RepeatEmit c s)
forall a. a -> Maybe a
Just (RepeatPos
RepeatHead, RepeatEmit c s
forall c s. RepeatEmit c s
RepeatEmit)

-- | @.emit@ modulator without argument after the @.repeat@ step. It
-- always returns 'Just'.
--
-- >>> toGremlin (source "g" & sV' [] &. gRepeat Nothing Nothing gEmitTail (gOut' []))
-- "g.V().repeat(__.out()).emit()"
--
-- @since 1.0.1.0
gEmitTail :: Maybe (RepeatPos, RepeatEmit c s)
gEmitTail :: Maybe (RepeatPos, RepeatEmit c s)
gEmitTail = (RepeatPos, RepeatEmit c s) -> Maybe (RepeatPos, RepeatEmit c s)
forall a. a -> Maybe a
Just (RepeatPos
RepeatTail, RepeatEmit c s
forall c s. RepeatEmit c s
RepeatEmit)

-- | @.emit@ modulator with a sub-traversal argument before the
-- @.repeat@ step. It always returns 'Just'.
--
-- >>> toGremlin (source "g" & sV' [] &. gRepeat Nothing Nothing (gEmitHeadT $ gHasLabel' "person") (gOut' []))
-- "g.V().emit(__.hasLabel(\"person\")).repeat(__.out())"
--
-- @since 1.0.1.0
gEmitHeadT :: (ToGTraversal g, WalkType c, WalkType cc, Split cc c) => g cc s e -> Maybe (RepeatPos, RepeatEmit c s)
gEmitHeadT :: g cc s e -> Maybe (RepeatPos, RepeatEmit c s)
gEmitHeadT g cc s e
trav = (RepeatPos, RepeatEmit c s) -> Maybe (RepeatPos, RepeatEmit c s)
forall a. a -> Maybe a
Just (RepeatPos
RepeatHead, GTraversal cc s e -> RepeatEmit c s
forall cc c s e.
(WalkType cc, WalkType c, Split cc c) =>
GTraversal cc s e -> RepeatEmit c s
RepeatEmitT (GTraversal cc s e -> RepeatEmit c s)
-> GTraversal cc s e -> RepeatEmit c s
forall a b. (a -> b) -> a -> b
$ g cc s e -> GTraversal cc s e
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> GTraversal c s e
toGTraversal g cc s e
trav)

-- | @.emit@ modulator with a sub-traversal argument after the
-- @.repeat@ step. It always returns 'Just'.
--
-- >>> toGremlin (source "g" & sV' [] &. gRepeat Nothing Nothing (gEmitTailT $ gHasLabel' "person") (gOut' []))
-- "g.V().repeat(__.out()).emit(__.hasLabel(\"person\"))"
--
-- @since 1.0.1.0
gEmitTailT :: (ToGTraversal g, WalkType c, WalkType cc, Split cc c) => g cc s e -> Maybe (RepeatPos, RepeatEmit c s)
gEmitTailT :: g cc s e -> Maybe (RepeatPos, RepeatEmit c s)
gEmitTailT g cc s e
trav = (RepeatPos, RepeatEmit c s) -> Maybe (RepeatPos, RepeatEmit c s)
forall a. a -> Maybe a
Just (RepeatPos
RepeatTail, GTraversal cc s e -> RepeatEmit c s
forall cc c s e.
(WalkType cc, WalkType c, Split cc c) =>
GTraversal cc s e -> RepeatEmit c s
RepeatEmitT (GTraversal cc s e -> RepeatEmit c s)
-> GTraversal cc s e -> RepeatEmit c s
forall a b. (a -> b) -> a -> b
$ g cc s e -> GTraversal cc s e
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> GTraversal c s e
toGTraversal g cc s e
trav)

-- | @.loops@ step.
--
-- >>> let loop_label = Just "the_loop"
-- >>> toGremlin (source "g" & sV' [] &. gRepeat loop_label (gUntilTail $ gLoops loop_label >>> gIs 3) Nothing (gOut' []))
-- "g.V().repeat(\"the_loop\",__.out()).until(__.loops(\"the_loop\").is(3))"
--
-- @since 1.0.1.0
gLoops :: Maybe RepeatLabel -> Walk Transform s Int
gLoops :: Maybe RepeatLabel -> Walk Transform s Int
gLoops Maybe RepeatLabel
mlabel = Text -> [Text] -> Walk Transform s Int
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"loops" ([Text] -> Walk Transform s Int) -> [Text] -> Walk Transform s Int
forall a b. (a -> b) -> a -> b
$ [Text] -> (RepeatLabel -> [Text]) -> Maybe RepeatLabel -> [Text]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\RepeatLabel
l -> [RepeatLabel -> Text
forall a. ToGreskell a => a -> Text
toGremlin RepeatLabel
l]) Maybe RepeatLabel
mlabel

-- | @.local@ step.
--
-- >>> toGremlin (source "g" & sV' [] &. gLocal ( gOut' [] >>> gLimit 3 ))
-- "g.V().local(__.out().limit(3))"
--
-- @since 1.0.1.0
gLocal :: (ToGTraversal g, WalkType c) => g c s e -> Walk c s e
gLocal :: g c s e -> Walk c s e
gLocal g c s e
t = Text -> [Text] -> Walk c s e
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"local" [g c s e -> Text
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> Text
travToG g c s e
t]

-- | @.union@ step.
--
-- >>> let key_age = ("age" :: Key AVertex Int)
-- >>> let key_birth_year = ("birth_year" :: Key AVertex Int)
-- >>> toGremlin (source "g" & sV' [] &. gUnion [gValues [key_age], gValues [key_birth_year]])
-- "g.V().union(__.values(\"age\"),__.values(\"birth_year\"))"
--
-- @since 1.0.1.0
gUnion :: (ToGTraversal g, WalkType c) => [g c s e] -> Walk c s e
gUnion :: [g c s e] -> Walk c s e
gUnion [g c s e]
ts = Text -> [Text] -> Walk c s e
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"union" ([Text] -> Walk c s e) -> [Text] -> Walk c s e
forall a b. (a -> b) -> a -> b
$ (g c s e -> Text) -> [g c s e] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map g c s e -> Text
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> Text
travToG [g c s e]
ts

-- | @.coalesce@ step.
--
-- Like 'gFlatMap', 'gCoalesce' always modifies path history.
--
-- >>> toGremlin (source "g" & sV' [] &. gCoalesce [gOut' [], gIn' []])
-- "g.V().coalesce(__.out(),__.in())"
--
-- @since 1.1.0.0
gCoalesce :: (ToGTraversal g, Split cc c, Lift Transform c, WalkType c, WalkType cc)
          => [g cc s e] -> Walk c s e
gCoalesce :: [g cc s e] -> Walk c s e
gCoalesce [g cc s e]
ts = Text -> [Text] -> Walk c s e
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"coalesce" ([Text] -> Walk c s e) -> [Text] -> Walk c s e
forall a b. (a -> b) -> a -> b
$ (g cc s e -> Text) -> [g cc s e] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map g cc s e -> Text
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> Text
travToG [g cc s e]
ts

-- | @.choose@ step with if-then-else style.
--
-- >>> let key_age = ("age" :: Key AVertex Int)
-- >>> toGremlin (source "g" & sV' [] &. gChoose3 (gHas2' key_age 30) (gIn' []) (gOut' []))
-- "g.V().choose(__.has(\"age\",30),__.in(),__.out())"
--
-- @since 1.0.1.0
gChoose3 :: (ToGTraversal g, Split cc c, WalkType cc, WalkType c)
         => g cc s ep -- ^ the predicate traversal.
         -> g c s e -- ^ The traversal executed if the predicate traversal outputs something.
         -> g c s e -- ^ The traversal executed if the predicate traversal outputs nothing.
         -> Walk c s e
gChoose3 :: g cc s ep -> g c s e -> g c s e -> Walk c s e
gChoose3 g cc s ep
pt g c s e
tt g c s e
ft = Text -> [Text] -> Walk c s e
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"choose"
                    [ g cc s ep -> Text
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> Text
travToG g cc s ep
pt,
                      g c s e -> Text
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> Text
travToG g c s e
tt,
                      g c s e -> Text
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> Text
travToG g c s e
ft
                    ]

-- | @.barrier@ step.
--
-- @since 1.0.1.0
gBarrier :: WalkType c
         => Maybe (Greskell Int)
         -- ^ Max number of traversers kept at this barrier.
         -> Walk c s s
gBarrier :: Maybe (Greskell Int) -> Walk c s s
gBarrier Maybe (Greskell Int)
mmax = Text -> [Text] -> Walk c s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"barrier" ([Text] -> Walk c s s) -> [Text] -> Walk c s s
forall a b. (a -> b) -> a -> b
$ [Text]
-> (Greskell Int -> [Text]) -> Maybe (Greskell Int) -> [Text]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Greskell Int
m -> [Greskell Int -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell Int
m]) Maybe (Greskell Int)
mmax

-- | @.dedup@ step without argument.
--
-- @.dedup@ step is 'Transform' because the filtering decision depends
-- on the sequence (order) of input elements.
--
-- >>> toGremlin (source "g" & sV' [] &. gDedup Nothing)
-- "g.V().dedup()"
-- >>> let key_age = ("age" :: Key AVertex Int)
-- >>> toGremlin (source "g" & sV' [] &. gDedup (Just $ gBy key_age))
-- "g.V().dedup().by(\"age\")"
--
-- @since 1.0.1.0
gDedup :: Maybe (ByProjection s e)
       -- ^ @.by@ modulator. If specified, the result of type @e@ is
       -- used as the criterion of deduplication.
       -> Walk Transform s s
gDedup :: Maybe (ByProjection s e) -> Walk Transform s s
gDedup Maybe (ByProjection s e)
mp = [Text] -> Maybe (ByProjection s e) -> Walk Transform s s
forall a b s.
[Text] -> Maybe (ByProjection a b) -> Walk Transform s s
gDedupGeneric [] Maybe (ByProjection s e)
mp

-- | @.dedup@ step with at least one argument. The tuple specified by
-- the 'AsLabel's is used as the criterion of deduplication.
--
-- >>> let label_a = ("a" :: AsLabel AVertex)
-- >>> let label_b = ("b" :: AsLabel AVertex)
-- >>> toGremlin (source "g" & sV' [] &. gAs label_a &. gOut' [] &. gAs label_b &. gDedupN label_a [label_b] Nothing)
-- "g.V().as(\"a\").out().as(\"b\").dedup(\"a\",\"b\")"
--
-- @since 1.0.1.0
gDedupN :: AsLabel a -> [AsLabel a] -> Maybe (ByProjection a e) -> Walk Transform s s
gDedupN :: AsLabel a
-> [AsLabel a] -> Maybe (ByProjection a e) -> Walk Transform s s
gDedupN AsLabel a
l [AsLabel a]
ls Maybe (ByProjection a e)
mp = [Text] -> Maybe (ByProjection a e) -> Walk Transform s s
forall a b s.
[Text] -> Maybe (ByProjection a b) -> Walk Transform s s
gDedupGeneric ((AsLabel a -> Text) -> [AsLabel a] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map AsLabel a -> Text
forall a. ToGreskell a => a -> Text
toGremlin (AsLabel a
l AsLabel a -> [AsLabel a] -> [AsLabel a]
forall a. a -> [a] -> [a]
: [AsLabel a]
ls)) Maybe (ByProjection a e)
mp

gDedupGeneric :: [Text] -> Maybe (ByProjection a b) -> Walk Transform s s
gDedupGeneric :: [Text] -> Maybe (ByProjection a b) -> Walk Transform s s
gDedupGeneric [Text]
args Maybe (ByProjection a b)
mp = 
  case Maybe (ByProjection a b)
mp of
    Maybe (ByProjection a b)
Nothing -> Walk Transform s s
main_walk
    Just (ByProjection p
g) -> Walk Transform s s -> [Walk Transform s s] -> Walk Transform s s
forall c s e.
WalkType c =>
Walk c s e -> [Walk c e e] -> Walk c s e
modulateWith Walk Transform s s
main_walk [Text -> [Text] -> Walk Transform s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"by" [p -> Text
forall a. ToGreskell a => a -> Text
toGremlin p
g]]
  where
    main_walk :: Walk Transform s s
main_walk = Text -> [Text] -> Walk Transform s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"dedup" [Text]
args


-- | Data types that mean a projection from one type to another.
class ProjectionLike p where
  type ProjectionLikeStart p
  -- ^ The start type of the projection.
  type ProjectionLikeEnd p
  -- ^ The end type of the projection.

instance ProjectionLike (Walk Filter s e) where
  type ProjectionLikeStart (Walk Filter s e) = s
  type ProjectionLikeEnd (Walk Filter s e) = e

instance ProjectionLike (GTraversal Filter s e) where
  type ProjectionLikeStart (GTraversal Filter s e) = s
  type ProjectionLikeEnd (GTraversal Filter s e) = e

instance ProjectionLike (Greskell (GraphTraversal Filter s e)) where
  type ProjectionLikeStart (Greskell (GraphTraversal Filter s e)) = s
  type ProjectionLikeEnd (Greskell (GraphTraversal Filter s e)) = e

instance ProjectionLike (Walk Transform s e) where
  type ProjectionLikeStart (Walk Transform s e) = s
  type ProjectionLikeEnd (Walk Transform s e) = e

instance ProjectionLike (GTraversal Transform s e) where
  type ProjectionLikeStart (GTraversal Transform s e) = s
  type ProjectionLikeEnd (GTraversal Transform s e) = e

instance ProjectionLike (Greskell (GraphTraversal Transform s e)) where
  type ProjectionLikeStart (Greskell (GraphTraversal Transform s e)) = s
  type ProjectionLikeEnd (Greskell (GraphTraversal Transform s e)) = e

instance ProjectionLike (Key s e) where
  type ProjectionLikeStart (Key s e) = s
  type ProjectionLikeEnd (Key s e) = e

instance ProjectionLike (Greskell (T s e)) where
  type ProjectionLikeStart (Greskell (T s e)) = s
  type ProjectionLikeEnd (Greskell (T s e)) = e

instance ProjectionLike (Greskell (s -> e)) where
  type ProjectionLikeStart (Greskell (s -> e)) = s
  type ProjectionLikeEnd (Greskell (s -> e)) = e

instance ProjectionLike (ByProjection s e) where
  type ProjectionLikeStart (ByProjection s e) = s
  type ProjectionLikeEnd (ByProjection s e) = e

-- | Projection from type @s@ to type @e@ used in @.by@ step. You can
-- also use 'gBy' to construct 'ByProjection'.
data ByProjection s e where
  ByProjection :: (ProjectionLike p, ToGreskell p) => p -> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)

-- | Projection by literal property key.
instance IsString (ByProjection s e) where
  fromString :: String -> ByProjection s e
fromString = Key s e -> ByProjection s e
forall p.
(ProjectionLike p, ToGreskell p) =>
p -> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
ByProjection (Key s e -> ByProjection s e)
-> (String -> Key s e) -> String -> ByProjection s e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Key s e
forall s e. String -> Key s e
toKey
    where
      toKey :: String -> Key s e
      toKey :: String -> Key s e
toKey = String -> Key s e
forall a. IsString a => String -> a
fromString

-- | @.by@ step with 1 argument, used for projection.
gBy :: (ProjectionLike p, ToGreskell p) => p -> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
gBy :: p -> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
gBy = p -> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
forall p.
(ProjectionLike p, ToGreskell p) =>
p -> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
ByProjection 

-- | Comparison of type @s@ used in @.by@ step. You can also use
-- 'gBy1' and 'gBy2' to construct 'ByComparator'.
data ByComparator s where
  -- | Type @s@ is projected to type @e@, and compared by the natural
  -- comparator of type @e@.
  ByComparatorProj :: ByProjection s e -> ByComparator s
  
  -- | Type @s@ is compared by the 'Comparator' @comp@.
  ByComparatorComp :: Comparator comp => Greskell comp -> ByComparator (CompareArg comp)
  
  -- | Type @s@ is projected to type @CompareArg comp@, and compared
  -- by the 'Comparator' @comp@.
  ByComparatorProjComp :: Comparator comp => ByProjection s (CompareArg comp) -> Greskell comp -> ByComparator s

-- | 'ByComparatorProj' by literal property key.
instance IsString (ByComparator s) where
  fromString :: String -> ByComparator s
fromString = ByProjection s Any -> ByComparator s
forall s e. ByProjection s e -> ByComparator s
ByComparatorProj (ByProjection s Any -> ByComparator s)
-> (String -> ByProjection s Any) -> String -> ByComparator s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByProjection s Any
forall a. IsString a => String -> a
fromString

-- | @.by@ step with 1 argument, used for comparison.
gBy1 :: (ProjectionLike p, ToGreskell p) => p -> ByComparator (ProjectionLikeStart p)
gBy1 :: p -> ByComparator (ProjectionLikeStart p)
gBy1 = ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
-> ByComparator (ProjectionLikeStart p)
forall s e. ByProjection s e -> ByComparator s
ByComparatorProj (ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
 -> ByComparator (ProjectionLikeStart p))
-> (p
    -> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p))
-> p
-> ByComparator (ProjectionLikeStart p)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p -> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
forall p.
(ProjectionLike p, ToGreskell p) =>
p -> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
gBy

-- | @.by@ step with 2 arguments, used for comparison.
gBy2 :: (ProjectionLike p, ToGreskell p, Comparator comp, ProjectionLikeEnd p ~ CompareArg comp)
     => p
     -> Greskell comp
     -> ByComparator (ProjectionLikeStart p)
gBy2 :: p -> Greskell comp -> ByComparator (ProjectionLikeStart p)
gBy2 p
p Greskell comp
c = ByProjection (ProjectionLikeStart p) (CompareArg comp)
-> Greskell comp -> ByComparator (ProjectionLikeStart p)
forall comp s.
Comparator comp =>
ByProjection s (CompareArg comp) -> Greskell comp -> ByComparator s
ByComparatorProjComp (p -> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
forall p.
(ProjectionLike p, ToGreskell p) =>
p -> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
gBy p
p) Greskell comp
c

-- | @.order@ step.
--
-- >>> let key_age = ("age" :: Key AVertex Int)
-- >>> toGremlin (source "g" & sV' [] &. gOrder [gBy1 key_age])
-- "g.V().order().by(\"age\")"
-- >>> toGremlin (source "g" & sV' [] &. gOrder [gBy2 key_age oDecr, gBy1 tId])
-- "g.V().order().by(\"age\",Order.decr).by(T.id)"
-- >>> toGremlin (source "g" & sV' [] &. gOrder [gBy2 (gOut' ["knows"] >>> gCount) oIncr, gBy2 tId oIncr])
-- "g.V().order().by(__.out(\"knows\").count(),Order.incr).by(T.id,Order.incr)"
--
-- 'ByComparator' is an 'IsString', meaning projection by the given
-- key.
--
-- >>> toGremlin (source "g" & sV' [] &. gOrder ["age"])
-- "g.V().order().by(\"age\")"
gOrder :: [ByComparator s] -- ^ following @.by@ steps.
       -> Walk Transform s s
gOrder :: [ByComparator s] -> Walk Transform s s
gOrder [ByComparator s]
bys = Walk Transform s s -> [Walk Transform s s] -> Walk Transform s s
forall c s e.
WalkType c =>
Walk c s e -> [Walk c e e] -> Walk c s e
modulateWith Walk Transform s s
forall s e. Walk Transform s e
order_step [Walk Transform s s]
by_steps
  where
    order_step :: Walk Transform s e
order_step = Text -> [Text] -> Walk Transform s e
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"order" []
    by_steps :: [Walk Transform s s]
by_steps = (ByComparator s -> Walk Transform s s)
-> [ByComparator s] -> [Walk Transform s s]
forall a b. (a -> b) -> [a] -> [b]
map (Text -> [Text] -> Walk Transform s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"by" ([Text] -> Walk Transform s s)
-> (ByComparator s -> [Text])
-> ByComparator s
-> Walk Transform s s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByComparator s -> [Text]
forall s. ByComparator s -> [Text]
toByArgs) [ByComparator s]
bys
    toByArgs :: ByComparator s -> [Text]
    toByArgs :: ByComparator s -> [Text]
toByArgs ByComparator s
bc = case ByComparator s
bc of
      ByComparatorProj (ByProjection p
p) -> [p -> Text
forall a. ToGreskell a => a -> Text
toGremlin p
p]
      ByComparatorComp Greskell comp
comp -> [Greskell comp -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell comp
comp]
      ByComparatorProjComp (ByProjection p
p) Greskell comp
comp -> [p -> Text
forall a. ToGreskell a => a -> Text
toGremlin p
p, Greskell comp -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell comp
comp]

-- | A 'ByProjection' associated with an 'AsLabel'. You can construct
-- it by 'gByL'.
--
-- @since 1.0.0.0
data LabeledByProjection s where
  LabeledByProjection :: AsLabel a -> ByProjection s a -> LabeledByProjection s

-- | @.by@ step associated with an 'AsLabel'.
--
-- @since 1.0.0.0
gByL :: (ProjectionLike p, ToGreskell p) => AsLabel (ProjectionLikeEnd p) -> p -> LabeledByProjection (ProjectionLikeStart p)
gByL :: AsLabel (ProjectionLikeEnd p)
-> p -> LabeledByProjection (ProjectionLikeStart p)
gByL AsLabel (ProjectionLikeEnd p)
l p
p = AsLabel (ProjectionLikeEnd p)
-> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
-> LabeledByProjection (ProjectionLikeStart p)
forall a s. AsLabel a -> ByProjection s a -> LabeledByProjection s
LabeledByProjection AsLabel (ProjectionLikeEnd p)
l (ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
 -> LabeledByProjection (ProjectionLikeStart p))
-> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
-> LabeledByProjection (ProjectionLikeStart p)
forall a b. (a -> b) -> a -> b
$ p -> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
forall p.
(ProjectionLike p, ToGreskell p) =>
p -> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
gBy p
p

-- | @.flatMap@ step.
--
-- @.flatMap@ step is at least as powerful as 'Transform', even if the
-- child walk is 'Filter' type. This is because @.flatMap@ step always
-- modifies the path of the Traverser.
--
-- >>> toGremlin (source "g" & sV' [] &. gFlatMap (gOut' ["knows"] >>> gOut' ["created"]))
-- "g.V().flatMap(__.out(\"knows\").out(\"created\"))"
--
-- @since 1.1.0.0
gFlatMap :: (Lift Transform c, Split cc c, ToGTraversal g, WalkType c, WalkType cc) => g cc s e -> Walk c s e
gFlatMap :: g cc s e -> Walk c s e
gFlatMap g cc s e
gt = Text -> [Text] -> Walk c s e
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"flatMap" [g cc s e -> Text
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> Text
travToG g cc s e
gt]

-- | Monomorphic version of 'gFlatMap'.
--
-- @since 1.1.0.0
gFlatMap' :: ToGTraversal g => g Transform s e -> Walk Transform s e
gFlatMap' :: g Transform s e -> Walk Transform s e
gFlatMap' g Transform s e
gt = g Transform s e -> Walk Transform s e
forall c cc (g :: * -> * -> * -> *) s e.
(Lift Transform c, Split cc c, ToGTraversal g, WalkType c,
 WalkType cc) =>
g cc s e -> Walk c s e
gFlatMap g Transform s e
gt

-- | @.V@ step.
--
-- For each input item, @.V@ step emits vertices selected by the
-- argument (or all vertices if the empty list is passed.)
--
-- @since 0.2.0.0
gV :: Vertex v => [Greskell (ElementID v)] -> Walk Transform s v
gV :: [Greskell (ElementID v)] -> Walk Transform s v
gV [Greskell (ElementID v)]
ids = Text -> [Text] -> Walk Transform s v
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"V" ([Text] -> Walk Transform s v) -> [Text] -> Walk Transform s v
forall a b. (a -> b) -> a -> b
$ (Greskell (ElementID v) -> Text)
-> [Greskell (ElementID v)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Greskell (ElementID v) -> Text
forall a. ToGreskell a => a -> Text
toGremlin [Greskell (ElementID v)]
ids

-- | Monomorphic version of 'gV'.
--
-- @since 0.2.0.0
gV' :: [Greskell (ElementID AVertex)] -> Walk Transform s AVertex
gV' :: [Greskell (ElementID AVertex)] -> Walk Transform s AVertex
gV' = [Greskell (ElementID AVertex)] -> Walk Transform s AVertex
forall v s.
Vertex v =>
[Greskell (ElementID v)] -> Walk Transform s v
gV

-- | @.constant@ step.
--
-- >>> toGremlin (source "g" & sV' [] &. gConstant (10 :: Greskell Int))
-- "g.V().constant(10)"
--
-- @since 1.0.1.0
gConstant :: Greskell a -> Walk Transform s a
gConstant :: Greskell a -> Walk Transform s a
gConstant Greskell a
v = Text -> [Text] -> Walk Transform s a
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"constant" [Greskell a -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell a
v]

-- | @.unfold@ step.
--
-- Note that we use 'AsIterator' here because basically the @.unfold@
-- step does the same thing as @IteratorUtils.asIterator@ function in
-- Tinkerpop. However, Tinkerpop's implementation of @.unfold@ step
-- doesn't necessarily use @asIterator@, so there may be some corner
-- cases where @asIterator@ and @.unfold@ step behave differently.
--
-- >>> toGremlin (source "g" & sV' [] &. gFold &. gUnfold)
-- "g.V().fold().unfold()"
--
-- @since 1.0.1.0
gUnfold :: AsIterator a => Walk Transform a (IteratorItem a)
gUnfold :: Walk Transform a (IteratorItem a)
gUnfold = Text -> [Text] -> Walk Transform a (IteratorItem a)
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"unfold" []

-- | @.as@ step.
--
-- @.as@ step is 'Transform' because it adds the label to the
-- traverser.
--
-- @since 0.2.2.0
gAs :: AsLabel a -> Walk Transform a a
gAs :: AsLabel a -> Walk Transform a a
gAs AsLabel a
l = Text -> [Text] -> Walk Transform a a
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"as" [AsLabel a -> Text
forall a. ToGreskell a => a -> Text
toGremlin AsLabel a
l]

-- | @.values@ step.
--
-- >>> toGremlin (source "g" & sV' [] &. gValues ["name", "age"])
-- "g.V().values(\"name\",\"age\")"
gValues :: Element s
        => [Key s e]
        -- ^ property keys
        -> Walk Transform s e
gValues :: [Key s e] -> Walk Transform s e
gValues = Text -> [Text] -> Walk Transform s e
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"values" ([Text] -> Walk Transform s e)
-> ([Key s e] -> [Text]) -> [Key s e] -> Walk Transform s e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Key s e -> Text) -> [Key s e] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Key s e -> Text
forall a. ToGreskell a => a -> Text
toGremlin

-- | @.properties@ step.
--
-- >>> toGremlin (source "g" & sV' [] &. gProperties ["age"])
-- "g.V().properties(\"age\")"
gProperties :: (Element s, Property p, ElementProperty s ~ p)
            => [Key s v]
            -> Walk Transform s (p v)
gProperties :: [Key s v] -> Walk Transform s (p v)
gProperties = Text -> [Text] -> Walk Transform s (p v)
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"properties" ([Text] -> Walk Transform s (p v))
-> ([Key s v] -> [Text]) -> [Key s v] -> Walk Transform s (p v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Key s v -> Text) -> [Key s v] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Key s v -> Text
forall a. ToGreskell a => a -> Text
toGremlin

-- | @.id@ step.
--
-- @since 0.2.1.0
gId :: Element s => Walk Transform s (ElementID s)
gId :: Walk Transform s (ElementID s)
gId = Text -> [Text] -> Walk Transform s (ElementID s)
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"id" []

-- | @.label@ step.
--
-- @since 0.2.1.0
gLabel :: Element s => Walk Transform s Text
gLabel :: Walk Transform s Text
gLabel = Text -> [Text] -> Walk Transform s Text
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"label" []

-- | @.valueMap@ step.
--
-- >>> toGremlin (source "g" & sV' [] &. gValueMap KeysNil)
-- "g.V().valueMap()"
-- >>> toGremlin (source "g" & sV' [] &. gValueMap ("name" -: "age" -: KeysNil))
-- "g.V().valueMap(\"name\",\"age\")"
--
-- @since 1.0.0.0
gValueMap :: Element s
          => Keys s
          -> Walk Transform s (PMap (ElementPropertyContainer s) GValue)
gValueMap :: Keys s
-> Walk Transform s (PMap (ElementPropertyContainer s) GValue)
gValueMap Keys s
keys = Text
-> [Text]
-> Walk Transform s (PMap (ElementPropertyContainer s) GValue)
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"valueMap" ([Text]
 -> Walk Transform s (PMap (ElementPropertyContainer s) GValue))
-> [Text]
-> Walk Transform s (PMap (ElementPropertyContainer s) GValue)
forall a b. (a -> b) -> a -> b
$ Keys s -> [Text]
forall a. Keys a -> [Text]
toGremlinKeys Keys s
keys
  where
    toGremlinKeys :: Keys a -> [Text]
toGremlinKeys Keys a
KeysNil = []
    toGremlinKeys (KeysCons Key a b
k Keys a
rest) = Key a b -> Text
forall a. ToGreskell a => a -> Text
toGremlin Key a b
k Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: Keys a -> [Text]
toGremlinKeys Keys a
rest

-- | @.select@ step with one argument.
--
-- @since 0.2.2.0
gSelect1 :: AsLabel a -> Walk Transform s a
gSelect1 :: AsLabel a -> Walk Transform s a
gSelect1 AsLabel a
l = Text -> [Text] -> Walk Transform s a
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"select" [AsLabel a -> Text
forall a. ToGreskell a => a -> Text
toGremlin AsLabel a
l]

-- | @.select@ step with more than one arguments.
--
-- @since 0.2.2.0
gSelectN :: AsLabel a -> AsLabel b -> [AsLabel c] -> Walk Transform s (SelectedMap GValue)
gSelectN :: AsLabel a
-> AsLabel b
-> [AsLabel c]
-> Walk Transform s (SelectedMap GValue)
gSelectN AsLabel a
l1 AsLabel b
l2 [AsLabel c]
ls = Text -> [Text] -> Walk Transform s (SelectedMap GValue)
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"select" ([AsLabel a -> Text
forall a. ToGreskell a => a -> Text
toGremlin AsLabel a
l1, AsLabel b -> Text
forall a. ToGreskell a => a -> Text
toGremlin AsLabel b
l2] [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (AsLabel c -> Text) -> [AsLabel c] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map AsLabel c -> Text
forall a. ToGreskell a => a -> Text
toGremlin [AsLabel c]
ls)

unsafeChangeEnd :: Walk c a b -> Walk c a b'
unsafeChangeEnd :: Walk c a b -> Walk c a b'
unsafeChangeEnd (Walk Text
t) = Text -> Walk c a b'
forall c s e. Text -> Walk c s e
Walk Text
t

byStep :: WalkType t => ByProjection a b -> Walk t c c
byStep :: ByProjection a b -> Walk t c c
byStep (ByProjection p
p) = Text -> [Text] -> Walk t c c
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"by" [p -> Text
forall a. ToGreskell a => a -> Text
toGremlin p
p]

-- | @.select@ step with one argument followed by @.by@ step.
--
-- @since 0.2.2.0
gSelectBy1 :: AsLabel a -> ByProjection a b -> Walk Transform s b
gSelectBy1 :: AsLabel a -> ByProjection a b -> Walk Transform s b
gSelectBy1 AsLabel a
l ByProjection a b
bp = Walk Transform s b -> [Walk Transform b b] -> Walk Transform s b
forall c s e.
WalkType c =>
Walk c s e -> [Walk c e e] -> Walk c s e
modulateWith (Walk Transform s a -> Walk Transform s b
forall c a b b'. Walk c a b -> Walk c a b'
unsafeChangeEnd (Walk Transform s a -> Walk Transform s b)
-> Walk Transform s a -> Walk Transform s b
forall a b. (a -> b) -> a -> b
$ AsLabel a -> Walk Transform s a
forall a s. AsLabel a -> Walk Transform s a
gSelect1 AsLabel a
l) [ByProjection a b -> Walk Transform b b
forall t a b c. WalkType t => ByProjection a b -> Walk t c c
byStep ByProjection a b
bp]

-- | @.select@ step with more than one arguments followed by @.by@
-- step.
--
-- @since 0.2.2.0
gSelectByN :: AsLabel a -> AsLabel a -> [AsLabel a] -> ByProjection a b -> Walk Transform s (SelectedMap b)
gSelectByN :: AsLabel a
-> AsLabel a
-> [AsLabel a]
-> ByProjection a b
-> Walk Transform s (SelectedMap b)
gSelectByN AsLabel a
l1 AsLabel a
l2 [AsLabel a]
ls ByProjection a b
bp = Walk Transform s (SelectedMap b)
-> [Walk Transform (SelectedMap b) (SelectedMap b)]
-> Walk Transform s (SelectedMap b)
forall c s e.
WalkType c =>
Walk c s e -> [Walk c e e] -> Walk c s e
modulateWith (Walk Transform s (SelectedMap GValue)
-> Walk Transform s (SelectedMap b)
forall c a b b'. Walk c a b -> Walk c a b'
unsafeChangeEnd (Walk Transform s (SelectedMap GValue)
 -> Walk Transform s (SelectedMap b))
-> Walk Transform s (SelectedMap GValue)
-> Walk Transform s (SelectedMap b)
forall a b. (a -> b) -> a -> b
$ AsLabel a
-> AsLabel a
-> [AsLabel a]
-> Walk Transform s (SelectedMap GValue)
forall a b c s.
AsLabel a
-> AsLabel b
-> [AsLabel c]
-> Walk Transform s (SelectedMap GValue)
gSelectN AsLabel a
l1 AsLabel a
l2 [AsLabel a]
ls) [ByProjection a b -> Walk Transform (SelectedMap b) (SelectedMap b)
forall t a b c. WalkType t => ByProjection a b -> Walk t c c
byStep ByProjection a b
bp]

-- | @.project@ step.
--
-- >>> let name_label = ("a" :: AsLabel Text)
-- >>> let name_key = ("name" :: Key AVertex Text)
-- >>> let count_label = ("b" :: AsLabel Int)
-- >>> toGremlin (source "g" & sV' [] &. gProject (gByL name_label name_key) [gByL count_label (gOut' [] >>> gCount), gByL "c" tId])
-- "g.V().project(\"a\",\"b\",\"c\").by(\"name\").by(__.out().count()).by(T.id)"
--
-- @since 1.0.0.0
gProject :: LabeledByProjection s -> [LabeledByProjection s] -> Walk Transform s (PMap Single GValue)
gProject :: LabeledByProjection s
-> [LabeledByProjection s] -> Walk Transform s (SelectedMap GValue)
gProject LabeledByProjection s
lp_head [LabeledByProjection s]
lps = (Walk Transform s (SelectedMap GValue)
 -> LabeledByProjection s -> Walk Transform s (SelectedMap GValue))
-> Walk Transform s (SelectedMap GValue)
-> [LabeledByProjection s]
-> Walk Transform s (SelectedMap GValue)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Walk Transform s (SelectedMap GValue)
-> LabeledByProjection s -> Walk Transform s (SelectedMap GValue)
forall a c s.
Walk Transform a c -> LabeledByProjection s -> Walk Transform a c
f (Text -> [Text] -> Walk Transform s (SelectedMap GValue)
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"project" [Text]
labels) (LabeledByProjection s
lp_head LabeledByProjection s
-> [LabeledByProjection s] -> [LabeledByProjection s]
forall a. a -> [a] -> [a]
: [LabeledByProjection s]
lps)
  where
    labels :: [Text]
labels = (LabeledByProjection s -> Text)
-> [LabeledByProjection s] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map LabeledByProjection s -> Text
forall s. LabeledByProjection s -> Text
toLabelGremlin (LabeledByProjection s
lp_head LabeledByProjection s
-> [LabeledByProjection s] -> [LabeledByProjection s]
forall a. a -> [a] -> [a]
: [LabeledByProjection s]
lps)
    toLabelGremlin :: LabeledByProjection s -> Text
toLabelGremlin (LabeledByProjection AsLabel a
l ByProjection s a
_) = AsLabel a -> Text
forall a. ToGreskell a => a -> Text
toGremlin AsLabel a
l
    f :: Walk Transform a c -> LabeledByProjection s -> Walk Transform a c
f Walk Transform a c
acc LabeledByProjection s
lp = Walk Transform a c
acc Walk Transform a c -> Walk Transform c c -> Walk Transform a c
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> LabeledByProjection s -> Walk Transform c c
forall s a. LabeledByProjection s -> Walk Transform a a
toByStep LabeledByProjection s
lp
    toByStep :: LabeledByProjection s -> Walk Transform a a
    toByStep :: LabeledByProjection s -> Walk Transform a a
toByStep (LabeledByProjection AsLabel a
_ (ByProjection p
p)) = Text -> [Text] -> Walk Transform a a
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"by" [p -> Text
forall a. ToGreskell a => a -> Text
toGremlin p
p]

-- | @.path@ step without modulation.
--
-- @since 1.1.0.0
gPath :: Walk Transform s (Path GValue)
gPath :: Walk Transform s (Path GValue)
gPath = Text -> [Text] -> Walk Transform s (Path GValue)
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"path" []

-- | @.path@ step with one or more @.by@ modulations.
--
-- >>> let inE = (gInE' [] :: Walk Transform AVertex AEdge)
-- >>> toGremlin (source "g" & sV' [] &. gOut' [] &. gPathBy "name" [gBy $ inE >>> gValues ["relation"]])
-- "g.V().out().path().by(\"name\").by(__.inE().values(\"relation\"))"
--
-- @since 1.1.0.0
gPathBy :: ByProjection a b -> [ByProjection a b] -> Walk Transform s (Path b)
gPathBy :: ByProjection a b -> [ByProjection a b] -> Walk Transform s (Path b)
gPathBy ByProjection a b
b1 [ByProjection a b]
bn = Walk Transform s (Path b)
-> [Walk Transform (Path b) (Path b)] -> Walk Transform s (Path b)
forall c s e.
WalkType c =>
Walk c s e -> [Walk c e e] -> Walk c s e
modulateWith (Text -> [Text] -> Walk Transform s (Path b)
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"path" []) ([Walk Transform (Path b) (Path b)] -> Walk Transform s (Path b))
-> [Walk Transform (Path b) (Path b)] -> Walk Transform s (Path b)
forall a b. (a -> b) -> a -> b
$ (ByProjection a b -> Walk Transform (Path b) (Path b))
-> [ByProjection a b] -> [Walk Transform (Path b) (Path b)]
forall a b. (a -> b) -> [a] -> [b]
map ByProjection a b -> Walk Transform (Path b) (Path b)
forall t a b c. WalkType t => ByProjection a b -> Walk t c c
byStep ([ByProjection a b] -> [Walk Transform (Path b) (Path b)])
-> [ByProjection a b] -> [Walk Transform (Path b) (Path b)]
forall a b. (a -> b) -> a -> b
$ ByProjection a b
b1 ByProjection a b -> [ByProjection a b] -> [ByProjection a b]
forall a. a -> [a] -> [a]
: [ByProjection a b]
bn

-- | @.fold@ step.
gFold :: Walk Transform a [a]
gFold :: Walk Transform a [a]
gFold = Text -> [Text] -> Walk Transform a [a]
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"fold" []

-- | @.count@ step.
gCount :: Walk Transform a Int
gCount :: Walk Transform a Int
gCount = Text -> [Text] -> Walk Transform a Int
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"count" []

genericTraversalWalk :: Vertex v => Text -> [Greskell Text] -> Walk Transform v e
genericTraversalWalk :: Text -> [Greskell Text] -> Walk Transform v e
genericTraversalWalk Text
method_name = Text -> [Text] -> Walk Transform v e
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
method_name ([Text] -> Walk Transform v e)
-> ([Greskell Text] -> [Text])
-> [Greskell Text]
-> Walk Transform v e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Greskell Text -> Text) -> [Greskell Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Greskell Text -> Text
forall a. ToGreskell a => a -> Text
toGremlin

-- | @.out@ step
gOut :: (Vertex v1, Vertex v2)
     => [Greskell Text] -- ^ edge labels
     -> Walk Transform v1 v2
gOut :: [Greskell Text] -> Walk Transform v1 v2
gOut = Text -> [Greskell Text] -> Walk Transform v1 v2
forall v e.
Vertex v =>
Text -> [Greskell Text] -> Walk Transform v e
genericTraversalWalk Text
"out"

-- | Monomorphic version of 'gOut'.
--
-- >>> toGremlin (source "g" & sV' [fmap ElementID $ gvalueInt (8 :: Int)] &. gOut' ["knows"])
-- "g.V(8).out(\"knows\")"
gOut' :: (Vertex v)
      => [Greskell Text] -- ^ edge labels
      -> Walk Transform v AVertex
gOut' :: [Greskell Text] -> Walk Transform v AVertex
gOut' = [Greskell Text] -> Walk Transform v AVertex
forall v1 v2.
(Vertex v1, Vertex v2) =>
[Greskell Text] -> Walk Transform v1 v2
gOut

-- | @.outE@ step
gOutE :: (Vertex v, Edge e)
      => [Greskell Text] -- ^ edge labels
      -> Walk Transform v e
gOutE :: [Greskell Text] -> Walk Transform v e
gOutE = Text -> [Greskell Text] -> Walk Transform v e
forall v e.
Vertex v =>
Text -> [Greskell Text] -> Walk Transform v e
genericTraversalWalk Text
"outE"

-- | Monomorphic version of 'gOutE'.
gOutE' :: (Vertex v)
       => [Greskell Text]
       -> Walk Transform v AEdge
gOutE' :: [Greskell Text] -> Walk Transform v AEdge
gOutE' = [Greskell Text] -> Walk Transform v AEdge
forall v e.
(Vertex v, Edge e) =>
[Greskell Text] -> Walk Transform v e
gOutE

-- | @.outV@ step.
--
-- @since 0.2.2.0
gOutV :: (Edge e, Vertex v) => Walk Transform e v
gOutV :: Walk Transform e v
gOutV = Text -> [Text] -> Walk Transform e v
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"outV" []

-- | Monomorphic version of 'gOutV'.
--
-- @since 0.2.2.0
gOutV' :: Edge e => Walk Transform e AVertex
gOutV' :: Walk Transform e AVertex
gOutV' = Walk Transform e AVertex
forall e v. (Edge e, Vertex v) => Walk Transform e v
gOutV

-- | @.in@ step
gIn :: (Vertex v1, Vertex v2)
    => [Greskell Text] -- ^ edge labels
    -> Walk Transform v1 v2
gIn :: [Greskell Text] -> Walk Transform v1 v2
gIn = Text -> [Greskell Text] -> Walk Transform v1 v2
forall v e.
Vertex v =>
Text -> [Greskell Text] -> Walk Transform v e
genericTraversalWalk Text
"in"

-- | Monomorphic version of 'gIn'.
gIn' :: (Vertex v)
     => [Greskell Text]
     -> Walk Transform v AVertex
gIn' :: [Greskell Text] -> Walk Transform v AVertex
gIn' = [Greskell Text] -> Walk Transform v AVertex
forall v1 v2.
(Vertex v1, Vertex v2) =>
[Greskell Text] -> Walk Transform v1 v2
gIn

-- | @.inE@ step.
gInE :: (Vertex v, Edge e)
     => [Greskell Text] -- ^ edge labels
     -> Walk Transform v e
gInE :: [Greskell Text] -> Walk Transform v e
gInE = Text -> [Greskell Text] -> Walk Transform v e
forall v e.
Vertex v =>
Text -> [Greskell Text] -> Walk Transform v e
genericTraversalWalk Text
"inE"

-- | Monomorphic version of 'gInE'.
gInE' :: (Vertex v)
      => [Greskell Text] -- ^ edge labels
      -> Walk Transform v AEdge
gInE' :: [Greskell Text] -> Walk Transform v AEdge
gInE' = [Greskell Text] -> Walk Transform v AEdge
forall v e.
(Vertex v, Edge e) =>
[Greskell Text] -> Walk Transform v e
gInE

-- | @.inV@ step.
--
-- @since 0.2.2.0
gInV :: (Edge e, Vertex v) => Walk Transform e v
gInV :: Walk Transform e v
gInV = Text -> [Text] -> Walk Transform e v
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"inV" []

-- | Monomorphic version of 'gInV'.
--
-- @since 0.2.2.0
gInV' :: Edge e => Walk Transform e AVertex
gInV' :: Walk Transform e AVertex
gInV' = Walk Transform e AVertex
forall e v. (Edge e, Vertex v) => Walk Transform e v
gInV

-- | @.sideEffect@ step that takes a traversal.
gSideEffect :: (ToGTraversal g, WalkType c, WalkType p, Split c p) => g c s e -> Walk p s s
gSideEffect :: g c s e -> Walk p s s
gSideEffect g c s e
walk = Text -> [Text] -> Walk p s s
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"sideEffect" [g c s e -> Text
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> Text
travToG g c s e
walk]

-- | Monomorphic version of 'gSideEffect'. The result walk is always
-- 'SideEffect' type.
--
-- >>> toGremlin (source "g" & sV' [] & liftWalk &. gHas2 "name" "marko" &. gSideEffect' (gAddV' "toshio"))
-- "g.V().has(\"name\",\"marko\").sideEffect(__.addV(\"toshio\"))"
gSideEffect' :: (ToGTraversal g, WalkType c, Split c SideEffect) => g c s e -> Walk SideEffect s s
gSideEffect' :: g c s e -> Walk SideEffect s s
gSideEffect' g c s e
w = g c s e -> Walk SideEffect s s
forall (g :: * -> * -> * -> *) c p s e.
(ToGTraversal g, WalkType c, WalkType p, Split c p) =>
g c s e -> Walk p s s
gSideEffect g c s e
w

-- | @.addV@ step with a label.
gAddV :: Vertex v => Greskell Text -> Walk SideEffect a v
gAddV :: Greskell Text -> Walk SideEffect a v
gAddV Greskell Text
label = Text -> [Text] -> Walk SideEffect a v
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"addV" [Greskell Text -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell Text
label]

-- | Monomorphic version of 'gAddV'.
gAddV' :: Greskell Text -> Walk SideEffect a AVertex
gAddV' :: Greskell Text -> Walk SideEffect a AVertex
gAddV' = Greskell Text -> Walk SideEffect a AVertex
forall v a. Vertex v => Greskell Text -> Walk SideEffect a v
gAddV

-- | @.drop@ step on 'Element'.
-- 
-- >>> toGremlin (source "g" & sV' [] &. gHas2 "name" "marko" & liftWalk &. gDrop)
-- "g.V().has(\"name\",\"marko\").drop()"
gDrop :: Element e => Walk SideEffect e e
gDrop :: Walk SideEffect e e
gDrop = Text -> [Text] -> Walk SideEffect e e
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"drop" []

-- | @.drop@ step on 'Property'.
--
-- >>> toGremlin (source "g" & sE' [] &. gProperties ["weight"] & liftWalk &. gDropP)
-- "g.E().properties(\"weight\").drop()"
gDropP :: Property p => Walk SideEffect (p a) (p a)
gDropP :: Walk SideEffect (p a) (p a)
gDropP = Text -> [Text] -> Walk SideEffect (p a) (p a)
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"drop" []

-- | Simple @.property@ step. It adds a value to the property.
--
-- >>> toGremlin (source "g" & sV' [] & liftWalk &. gProperty "age" (20 :: Greskell Int))
-- "g.V().property(\"age\",20)"
--
-- @since 0.2.0.0
gProperty :: Element e
          => Key e v -- ^ key of the property
          -> Greskell v -- ^ value of the property
          -> Walk SideEffect e e
gProperty :: Key e v -> Greskell v -> Walk SideEffect e e
gProperty Key e v
key Greskell v
val = Text -> [Text] -> Walk SideEffect e e
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"property" [Key e v -> Text
forall a. ToGreskell a => a -> Text
toGremlin Key e v
key, Greskell v -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell v
val]

-- | @.property@ step for 'Vertex'.
--
-- >>> let key_location = "location" :: Key AVertex Text
-- >>> let key_since = "since" :: Key (AVertexProperty Text) Text
-- >>> let key_score = "score" :: Key (AVertexProperty Text) Int
-- >>> toGremlin (source "g" & sV' [] & liftWalk &. gPropertyV (Just cList) key_location "New York" [key_since =: "2012-09-23", key_score =: 8])
-- "g.V().property(list,\"location\",\"New York\",\"since\",\"2012-09-23\",\"score\",8)"
--
-- @since 0.2.0.0
gPropertyV :: (Vertex e, vp ~ ElementProperty e, Property vp, Element (vp v))
           => Maybe (Greskell Cardinality) -- ^ optional cardinality of the vertex property.
           -> Key e v -- ^ key of the vertex property
           -> Greskell v -- ^ value of the vertex property
           -> [KeyValue (vp v)] -- ^ optional meta-properties for the vertex property.
           -> Walk SideEffect e e
gPropertyV :: Maybe (Greskell Cardinality)
-> Key e v
-> Greskell v
-> [KeyValue (vp v)]
-> Walk SideEffect e e
gPropertyV Maybe (Greskell Cardinality)
mcard Key e v
key Greskell v
val [KeyValue (vp v)]
metaprops = Text -> [Text] -> Walk SideEffect e e
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"property" ([Text]
arg_card [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Text]
arg_keyval [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Text]
arg_metaprops)
  where
    arg_card :: [Text]
arg_card = [Text]
-> (Greskell Cardinality -> [Text])
-> Maybe (Greskell Cardinality)
-> [Text]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Greskell Cardinality
card -> [Greskell Cardinality -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell Cardinality
card]) Maybe (Greskell Cardinality)
mcard
    arg_keyval :: [Text]
arg_keyval = [Key e v -> Text
forall a. ToGreskell a => a -> Text
toGremlin Key e v
key, Greskell v -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell v
val]
    arg_metaprops :: [Text]
arg_metaprops = KeyValue (vp v) -> [Text]
forall a. KeyValue a -> [Text]
expand (KeyValue (vp v) -> [Text]) -> [KeyValue (vp v)] -> [Text]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [KeyValue (vp v)]
metaprops
      where
        expand :: KeyValue a -> [Text]
expand (KeyValue Key a b
meta_key Greskell b
meta_val) = [Key a b -> Text
forall a. ToGreskell a => a -> Text
toGremlin Key a b
meta_key, Greskell b -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell b
meta_val]
        expand (KeyNoValue Key a b
_) = []

-- | Vertex anchor for 'gAddE'. It corresponds to @.from@ or @.to@
-- step following an @.addE@ step.
--
-- Type @s@ is the input Vertex for the @.addE@ step. Type @e@ is the
-- type of the anchor Vertex that the 'AddAnchor' yields. So, @.addE@
-- step creates an edge between @s@ and @e@.
--
-- @since 0.2.0.0
data AddAnchor s e = AddAnchor Text (GTraversal Transform s e)

anchorStep :: WalkType c => AddAnchor s e -> Walk c edge edge
anchorStep :: AddAnchor s e -> Walk c edge edge
anchorStep (AddAnchor Text
step_name GTraversal Transform s e
subtraversal) = Text -> [Text] -> Walk c edge edge
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
step_name [GTraversal Transform s e -> Text
forall a. ToGreskell a => a -> Text
toGremlin GTraversal Transform s e
subtraversal]

-- | @.from@ step with a traversal.
-- 
-- @since 0.2.0.0
gFrom :: (ToGTraversal g) => g Transform s e -> AddAnchor s e
gFrom :: g Transform s e -> AddAnchor s e
gFrom = Text -> GTraversal Transform s e -> AddAnchor s e
forall s e. Text -> GTraversal Transform s e -> AddAnchor s e
AddAnchor Text
"from" (GTraversal Transform s e -> AddAnchor s e)
-> (g Transform s e -> GTraversal Transform s e)
-> g Transform s e
-> AddAnchor s e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. g Transform s e -> GTraversal Transform s e
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> GTraversal c s e
toGTraversal

-- | @.to@ step with a traversal.
--
-- @since 0.2.0.0
gTo :: (ToGTraversal g) => g Transform s e -> AddAnchor s e
gTo :: g Transform s e -> AddAnchor s e
gTo = Text -> GTraversal Transform s e -> AddAnchor s e
forall s e. Text -> GTraversal Transform s e -> AddAnchor s e
AddAnchor Text
"to" (GTraversal Transform s e -> AddAnchor s e)
-> (g Transform s e -> GTraversal Transform s e)
-> g Transform s e
-> AddAnchor s e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. g Transform s e -> GTraversal Transform s e
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> GTraversal c s e
toGTraversal

-- | @.addE@ step. Supported since TinkerPop 3.1.0.
--
-- >>> let key_name = "name" :: Key AVertex Text
-- >>> toGremlin (source "g" & sV' [] & liftWalk &. gAddE' "knows" (gFrom $ gV' [] >>> gHas2 key_name "marko"))
-- "g.V().addE(\"knows\").from(__.V().has(\"name\",\"marko\"))"
-- >>> toGremlin (source "g" & sV' [] &. gHas2 key_name "marko" & liftWalk &. gAddE' "knows" (gTo $ gV' []))
-- "g.V().has(\"name\",\"marko\").addE(\"knows\").to(__.V())"
-- 
-- @since 0.2.0.0
gAddE :: (Vertex vs, Vertex ve, Edge e)
      => Greskell Text
      -> AddAnchor vs ve
      -> Walk SideEffect vs e
gAddE :: Greskell Text -> AddAnchor vs ve -> Walk SideEffect vs e
gAddE Greskell Text
label AddAnchor vs ve
anch = (Text -> [Text] -> Walk SideEffect vs e
forall c s e. WalkType c => Text -> [Text] -> Walk c s e
unsafeWalk Text
"addE" [Greskell Text -> Text
forall a. ToGreskell a => a -> Text
toGremlin Greskell Text
label]) Walk SideEffect vs e -> Walk SideEffect e e -> Walk SideEffect vs e
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> AddAnchor vs ve -> Walk SideEffect e e
forall c s e edge. WalkType c => AddAnchor s e -> Walk c edge edge
anchorStep AddAnchor vs ve
anch

-- | Monomorphic version of 'gAddE'.
-- 
-- @since 0.2.0.0
gAddE' :: Greskell Text -> AddAnchor AVertex AVertex -> Walk SideEffect AVertex AEdge
gAddE' :: Greskell Text
-> AddAnchor AVertex AVertex -> Walk SideEffect AVertex AEdge
gAddE' = Greskell Text
-> AddAnchor AVertex AVertex -> Walk SideEffect AVertex AEdge
forall vs ve e.
(Vertex vs, Vertex ve, Edge e) =>
Greskell Text -> AddAnchor vs ve -> Walk SideEffect vs e
gAddE