Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pre 1.3 #82

Merged
merged 8 commits into from
Mar 11, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions src/Diagrams/Core/Measure.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeFamilies #-}
module Diagrams.Core.Measure
( Measured (..)
, Measure
Expand All @@ -20,20 +20,28 @@ import Control.Applicative
import Control.Lens
import qualified Control.Monad.Reader as R
import Data.Distributive
import Data.Typeable
import Data.Functor.Rep
import Data.Semigroup
import Data.Typeable

import Diagrams.Core.V
import Diagrams.Core.V

import Linear.Vector

-- (local, global, normalized) -> output
-- | 'Measured n a' is an object that depends on 'local', 'normalized'
-- and 'global' scales. The 'normalized' and 'global' scales are
-- calculated when rendering a diagram.
--
-- For attributes, the 'local' scale gets multiplied by the average
-- scale of the transform.
newtype Measured n a = Measured { unmeasure :: (n,n,n) -> a }
deriving (Typeable, Functor, Applicative, Monad, Additive, R.MonadReader (n,n,n))
-- (local, global, normalized) -> output

type instance V (Measured n a) = V a
type instance N (Measured n a) = N a

-- | A measure is a 'Measured' number.
type Measure n = Measured n n

-- | @fromMeasured globalScale normalizedScale measure -> a@
Expand All @@ -52,7 +60,7 @@ local x = views _1 (*x)
global :: Num n => n -> Measure n
global x = views _2 (*x)

-- | Normalized units get scaled so that one normalized unit is the size of the
-- | Normalized units get scaled so that one normalized unit is the size of the
-- final diagram.
normalized :: Num n => n -> Measure n
normalized x = views _3 (*x)
Expand Down Expand Up @@ -115,10 +123,14 @@ instance Monoid a => Monoid (Measured n a) where
mempty = pure mempty
mappend = liftA2 mappend


instance Distributive (Measured n) where
distribute a = Measured $ \x -> fmap (\(Measured m) -> m x) a

instance Representable (Measured n) where
type Rep (Measured n) = (n,n,n)
tabulate = Measured
index = unmeasure

instance Profunctor Measured where
lmap f (Measured m) = Measured $ \(l,g,n) -> m (f l, f g, f n)
rmap f (Measured m) = Measured $ f . m
Expand Down
66 changes: 39 additions & 27 deletions src/Diagrams/Core/Names.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
-----------------------------------------------------------------------------
-- |
-- Module : Diagrams.Core.Names
-- Copyright : (c) 2011 diagrams-core team (see LICENSE)
-- Copyright : (c) 2011-2015 diagrams-core team (see LICENSE)
-- License : BSD-style (see LICENSE)
-- Maintainer : diagrams-discuss@googlegroups.com
--
Expand All @@ -19,20 +19,20 @@
-----------------------------------------------------------------------------

module Diagrams.Core.Names
(-- * Names
-- ** Atomic names
AName(..)
(-- * Names
-- ** Atomic names
AName(..)
, _AName

-- ** Names
, Name(..), IsName(..), (.>)
-- ** Names
, Name(..), IsName(..), (.>)

-- ** Qualifiable
, Qualifiable(..)
-- ** Qualifiable
, Qualifiable(..)

) where
) where

import Control.Lens (over, Wrapped(..), Rewrapped, iso, _Unwrapping')
import Data.List (intercalate)
import Control.Lens hiding ((.>))
import qualified Data.Map as M
import Data.Semigroup
import qualified Data.Set as S
Expand Down Expand Up @@ -81,6 +81,7 @@ instance IsName Float
instance IsName Double
instance IsName Integer
instance IsName a => IsName [a]
instance IsName a => IsName (Maybe a)
instance (IsName a, IsName b) => IsName (a,b)
instance (IsName a, IsName b, IsName c) => IsName (a,b,c)

Expand All @@ -106,20 +107,31 @@ instance Ord AName where
Nothing -> typeOf a1 `compare` typeOf a2

instance Show AName where
show (AName a) = show a
showsPrec d (AName a) = showParen (d > 10) $
showString "AName " . showsPrec 11 a

-- | Prism onto 'AName'.
_AName :: (Typeable a, Ord a, Show a) => Prism' AName a
_AName = prism' AName (\(AName a) -> cast a)

-- | A (qualified) name is a (possibly empty) sequence of atomic names.
newtype Name = Name [AName]
deriving (Eq, Ord, Semigroup, Monoid, Typeable)

instance Rewrapped Name Name
instance Wrapped Name where
type Unwrapped Name = [AName]
_Wrapped' = iso (\(Name ans) -> ans) Name

instance Rewrapped Name Name
_Wrapped' = iso (\(Name ns) -> ns) Name

instance Show Name where
show (Name ns) = intercalate " .> " $ map show ns
showsPrec d (Name xs) = case xs of
[] -> showParen (d > 10) $ showString "Name []"
[n] -> showParen (d > 10) $ showString "toName " . showsName 11 n
(n:ns) -> showParen (d > 5) $ showsName 6 n . go ns
where
go (y:ys) = showString " .> " . showsName 6 y . go ys
go _ = id
where showsName dd (AName a) = showsPrec dd a

instance IsName Name where
toName = id
Expand All @@ -134,35 +146,35 @@ a1 .> a2 = toName a1 <> toName a2
-- prefixing them with a name.
class Qualifiable q where
-- | Qualify with the given name.
(|>) :: IsName a => a -> q -> q
(.>>) :: IsName a => a -> q -> q

-- | Of course, names can be qualified using @(.>)@.
instance Qualifiable Name where
(|>) = (.>)
(.>>) = (.>)

instance Qualifiable a => Qualifiable (TransInv a) where
(|>) n = over (_Unwrapping' TransInv) (n |>)
(.>>) n = over (_Unwrapping' TransInv) (n .>>)

instance (Qualifiable a, Qualifiable b) => Qualifiable (a,b) where
n |> (a,b) = (n |> a, n |> b)
n .>> (a,b) = (n .>> a, n .>> b)

instance (Qualifiable a, Qualifiable b, Qualifiable c) => Qualifiable (a,b,c) where
n |> (a,b,c) = (n |> a, n |> b, n |> c)
n .>> (a,b,c) = (n .>> a, n .>> b, n .>> c)

instance Qualifiable a => Qualifiable [a] where
n |> as = map (n |>) as
n .>> as = map (n .>>) as

instance (Ord a, Qualifiable a) => Qualifiable (S.Set a) where
n |> s = S.map (n |>) s
n .>> s = S.map (n .>>) s

instance Qualifiable a => Qualifiable (M.Map k a) where
n |> m = fmap (n |>) m
n .>> m = fmap (n .>>) m

instance Qualifiable a => Qualifiable (b -> a) where
n |> f = (n |>) . f
n .>> f = (n .>>) . f

instance Qualifiable a => Qualifiable (Measured n a) where
n |> m = fmap (n |>) m
n .>> m = fmap (n .>>) m

infixr 5 |>
infixr 5 .>>
infixr 5 .>
34 changes: 24 additions & 10 deletions src/Diagrams/Core/Style.hs
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ class (Typeable a, Semigroup a) => AttributeClass a
-- and some are affected by transformations and can be modified
-- generically.
data Attribute (v :: * -> *) n :: * where
Attribute :: AttributeClass a => a -> Attribute v n
MAttribute :: AttributeClass a => Measured n a -> Attribute v n
TAttribute :: (AttributeClass a, Transformable a, V a ~ v, N a ~ n) => a -> Attribute v n
Attribute :: AttributeClass a => a -> Attribute v n
MAttribute :: AttributeClass a => Measured n a -> Attribute v n
TAttribute :: (AttributeClass a, Transformable a, V a ~ v, N a ~ n) => a -> Attribute v n

type instance V (Attribute v n) = v
type instance N (Attribute v n) = n
Expand All @@ -136,7 +136,15 @@ instance Typeable n => Semigroup (Attribute v n) where
instance (Additive v, Traversable v, Floating n) => Transformable (Attribute v n) where
transform _ (Attribute a) = Attribute a
transform t (MAttribute a) = MAttribute $ scaleLocal (avgScale t) a
transform t (TAttribute a) = TAttribute (transform t a)
transform t (TAttribute a) = TAttribute $ transform t a

-- | Shows the kind of attribute and the type contained in the
-- attribute.
instance Typeable n => Show (Attribute v n) where
showsPrec d attr = showParen (d > 10) $ case attr of
Attribute a -> showString "Attribute " . showsPrec 11 (typeOf a)
MAttribute a -> showString "MAttribute " . showsPrec 11 (mType a)
TAttribute a -> showString "TAttribute " . showsPrec 11 (typeOf a)

-- | Unwrap an unknown 'Attribute' type, performing a dynamic (but
-- safe) check on the type of the result. If the required type
Expand Down Expand Up @@ -249,6 +257,11 @@ instance (Additive v, Traversable v, Floating n) => Transformable (Style v n) wh
-- | Styles have no action on other monoids.
instance A.Action (Style v n) m

-- | Show the attributes in the style.
instance Typeable n => Show (Style v n) where
showsPrec d sty = showParen (d > 10) $
showString "Style " . showsPrec d (sty ^.. each)

-- making styles -------------------------------------------------------

-- | Turn an attribute into a style. An easier way to make a style is to
Expand Down Expand Up @@ -283,29 +296,30 @@ unmeasureAttrs g n = over each (unmeasureAttribute g n)
-- style lenses --------------------------------------------------------

mkAttrLens :: forall v n a. Typeable a
=> Prism' (Attribute v n) a
=> (a -> TypeRep)
-> Prism' (Attribute v n) a
-> Lens' (Style v n) (Maybe a)
mkAttrLens p f sty =
mkAttrLens tyF p f sty =
f (sty ^? ix ty . p) <&> \mAtt -> sty & at ty .~ (review p <$> mAtt)
where ty = typeOf (undefined :: a)
where ty = tyF (undefined :: a)
{-# INLINE mkAttrLens #-}

-- | Lens onto a plain attribute of a style.
atAttr :: AttributeClass a
=> Lens' (Style v n) (Maybe a)
atAttr = mkAttrLens _Attribute
atAttr = mkAttrLens typeOf _Attribute
{-# INLINE atAttr #-}

-- | Lens onto a measured attribute of a style.
atMAttr :: (AttributeClass a, Typeable n)
=> Lens' (Style v n) (Maybe (Measured n a))
atMAttr = mkAttrLens _MAttribute
atMAttr = mkAttrLens mType _MAttribute
{-# INLINE atMAttr #-}

-- | Lens onto a transformable attribute of a style.
atTAttr :: (V a ~ v, N a ~ n, AttributeClass a, Transformable a)
=> Lens' (Style v n) (Maybe a)
atTAttr = mkAttrLens _TAttribute
atTAttr = mkAttrLens typeOf _TAttribute
{-# INLINE atTAttr #-}

-- applying styles -----------------------------------------------------
Expand Down
5 changes: 1 addition & 4 deletions src/Diagrams/Core/Transform.hs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ import Data.Functor.Rep

import Diagrams.Core.HasOrigin
import Diagrams.Core.Points ()
import Diagrams.Core.Measure
import Diagrams.Core.V

------------------------------------------------------------
Expand Down Expand Up @@ -351,9 +350,6 @@ instance ( V t ~ v, N t ~ n, V t ~ V s, N t ~ N s, Functor v, Num n
=> Transformable (s -> t) where
transform tr f = transform tr . f . transform (inv tr)

instance Transformable t => Transformable (Measured n t) where
transform = fmap . transform

instance Transformable t => Transformable [t] where
transform = map . transform

Expand Down Expand Up @@ -418,3 +414,4 @@ scale :: (InSpace v n a, Eq n, Fractional n, Transformable a)
=> n -> a -> a
scale 0 = error "scale by zero! Halp!" -- XXX what should be done here?
scale s = transform $ scaling s

42 changes: 22 additions & 20 deletions src/Diagrams/Core/Types.hs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}

{-# OPTIONS_GHC -fno-warn-orphans #-}
-- We have some orphan Action instances here, but since Action is a multi-param
Expand Down Expand Up @@ -131,16 +131,18 @@ module Diagrams.Core.Types
) where

import Control.Arrow (first, second, (***))
import Control.Lens (Lens', Rewrapped, Wrapped (..), iso, lens, over, view,
(^.), _Wrapped, _Wrapping, Prism', prism')
import Control.Lens (Lens', Prism', Rewrapped,
Wrapped (..), iso, lens, over,
prism', view, (^.), _Wrapped,
_Wrapping)
import Control.Monad (mplus)
import Data.Typeable
import Data.List (isSuffixOf)
import qualified Data.Map as M
import Data.Maybe (fromMaybe, listToMaybe)
import Data.Semigroup
import qualified Data.Traversable as T
import Data.Tree
import Data.Typeable

import Data.Monoid.Action
import Data.Monoid.Coproduct
Expand Down Expand Up @@ -598,7 +600,7 @@ instance (OrderedField n, Metric v, Semigroup m)
-- now be referred to using the qualification prefix.
instance (Metric v, OrderedField n, Semigroup m)
=> Qualifiable (QDiagram b v n m) where
(|>) = over _Wrapped' . D.applyD . inj . toName
(.>>) = over _Wrapped' . D.applyD . inj . toName


------------------------------------------------------------
Expand Down Expand Up @@ -722,7 +724,7 @@ instance (Metric v, Floating n)
-- ns@ is the same 'SubMap' except with every name qualified by
-- @a@.
instance Qualifiable (SubMap b v n m) where
a |> (SubMap m) = SubMap $ M.mapKeys (a |>) m
a .>> (SubMap m) = SubMap $ M.mapKeys (a .>>) m

-- | Construct a 'SubMap' from a list of associations between names
-- and subdiagrams.
Expand All @@ -735,7 +737,7 @@ rememberAs n b = over _Wrapped' $ M.insertWith (++) (toName n) [mkSubdiagram b]

-- | A name acts on a name map by qualifying every name in it.
instance Action Name (SubMap b v n m) where
act = (|>)
act = (.>>)

instance Action Name a => Action Name (Deletable a) where
act n (Deletable l a r) = Deletable l (act n a) r
Expand Down