module Diagrams.Core.Query
( Query (..)
) where
import Control.Applicative
import Control.Lens
import Data.Semigroup
import Data.Distributive
import Data.Functor.Rep
import Data.Profunctor
import Data.Profunctor.Sieve
import Data.Profunctor.Closed
import qualified Data.Profunctor.Rep as P
import Linear.Affine
import Linear.Vector
import Diagrams.Core.HasOrigin
import Diagrams.Core.Transform
import Diagrams.Core.V
newtype Query v n m = Query { runQuery :: Point v n -> m }
deriving (Functor, Applicative, Monad, Semigroup, Monoid)
instance Distributive (Query v n) where
distribute a = Query $ \p -> fmap (\(Query q) -> q p) a
instance Representable (Query v n) where
type Rep (Query v n) = Point v n
tabulate = Query
index = runQuery
instance Functor v => Profunctor (Query v) where
lmap f (Query q) = Query $ \p -> q (fmap f p)
rmap = fmap
instance Functor v => Cosieve (Query v) (Point v) where
cosieve = runQuery
instance Functor v => Closed (Query v) where
closed (Query fab) = Query $ \fxa x -> fab (fmap ($ x) fxa)
instance Functor v => Costrong (Query v) where
unfirst (Query f) = Query f'
where f' fa = b where (b, d) = f ((\a -> (a, d)) <$> fa)
unsecond (Query f) = Query f'
where f' fa = b where (d, b) = f ((,) d <$> fa)
instance Functor v => P.Corepresentable (Query v) where
type Corep (Query v) = Point v
cotabulate = Query
queryPoint :: Setter (Query v' n' m) (Query v n m) (Point v n) (Point v' n')
queryPoint = sets $ \f (Query q) -> Query $ q . f
instance Wrapped (Query v n m) where
type Unwrapped (Query v n m) = Point v n -> m
_Wrapped' = iso runQuery Query
instance Rewrapped (Query v a m) (Query v' a' m')
type instance V (Query v n m) = v
type instance N (Query v n m) = n
instance (Additive v, Num n) => HasOrigin (Query v n m) where
moveOriginTo (P u) = queryPoint %~ (.+^ u)
instance (Additive v, Num n) => Transformable (Query v n m) where
transform t = queryPoint %~ papply (inv t)