{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses #-} ----------------------------------------------------------------------------- -- | -- Module : Diagrams.Query -- Copyright : (c) 2013 diagrams-lib team (see LICENSE) -- License : BSD-style (see LICENSE) -- Maintainer : diagrams-discuss@googlegroups.com -- -- A query is a function that maps points in a vector space to values -- in some monoid. Queries naturally form a monoid, with two queries -- being combined pointwise. -- ----------------------------------------------------------------------------- module Diagrams.Query ( -- * Queries Query(..) , HasQuery (..) , sample , inquire -- ** Queries on diagrams , query , value , resetValue , clearValue ) where import Data.Monoid import Diagrams.Core -- | Types which can answer a 'Query' about points inside the geometric -- object. -- -- If @t@ and @m@ are both a 'Semigroup's, 'getQuery' should satisfy -- -- @ -- 'getQuery' (t1 <> t2) = 'getQuery' t1 <> 'getQuery' t2 -- @ class HasQuery t m | t -> m where -- | Extract the query of an object. getQuery :: t -> Query (V t) (N t) m instance HasQuery (Query v n m) m where getQuery = id instance Monoid m => HasQuery (QDiagram b v n m) m where getQuery = query -- | Test if a point is not equal to 'mempty'. -- -- @ -- 'inquire' :: 'QDiagram' b v n 'Any' -> 'Point' v n -> 'Bool' -- 'inquire' :: 'Query' v n 'Any' -> 'Point' v n -> 'Bool' -- 'inquire' :: 'Diagrams.BoundingBox.BoundingBox' v n -> 'Point' v n -> 'Bool' -- @ inquire :: HasQuery t Any => t -> Point (V t) (N t) -> Bool inquire t = getAny . sample t -- | Sample a diagram's query function at a given point. -- -- @ -- 'sample' :: 'QDiagram' b v n m -> 'Point' v n -> m -- 'sample' :: 'Query' v n m -> 'Point' v n -> m -- 'sample' :: 'Diagrams.BoundingBox.BoundingBox' v n -> 'Point' v n -> 'Any' -- 'sample' :: 'Diagrams.Path.Path' 'V2' 'Double' -> 'Point' v n -> 'Diagrams.TwoD.Path.Crossings' -- @ sample :: HasQuery t m => t -> Point (V t) (N t) -> m sample = runQuery . getQuery -- | Set the query value for 'True' points in a diagram (/i.e./ points -- \"inquire\" the diagram); 'False' points will be set to 'mempty'. value :: Monoid m => m -> QDiagram b v n Any -> QDiagram b v n m value m = fmap fromAny where fromAny (Any True) = m fromAny (Any False) = mempty -- | Reset the query values of a diagram to @True@/@False@: any values -- equal to 'mempty' are set to 'False'; any other values are set to -- 'True'. resetValue :: (Eq m, Monoid m) => QDiagram b v n m -> QDiagram b v n Any resetValue = fmap toAny where toAny m | m == mempty = Any False | otherwise = Any True -- | Set all the query values of a diagram to 'False'. clearValue :: QDiagram b v n m -> QDiagram b v n Any clearValue = fmap (const (Any False))