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

Convert from newtype to lens #124

Merged
merged 8 commits into from
Oct 6, 2013
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
1 change: 0 additions & 1 deletion diagrams-lib.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ Library
colour >= 2.3.2 && < 2.4,
data-default-class < 0.1,
pretty >= 1.0.1.2 && < 1.2,
newtype >= 0.2 && < 0.3,
fingertree >= 0.1 && < 0.2,
intervals >= 0.2.2 && < 0.3,
lens >= 3.9 && < 3.10
Expand Down
4 changes: 2 additions & 2 deletions src/Diagrams/CubicSpline.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import Diagrams.TrailLike (TrailLike (..))
-- for e.g. the Fractional (Double, Double) instance
import Data.NumInstances.Tuple ()

import Control.Newtype
import Data.AffineSpace.Point
import Data.VectorSpace

-- | Construct a spline path-like thing of cubic segments from a list of
Expand All @@ -53,7 +53,7 @@ import Data.VectorSpace
-- For more information, see <http://mathworld.wolfram.com/CubicSpline.html>.
cubicSpline :: (TrailLike t, Fractional (V t)) => Bool -> [Point (V t)] -> t
cubicSpline closed [] = trailLike . closeIf closed $ emptyLine `at` origin
cubicSpline closed ps = flattenBeziers . map f . solveCubicSplineCoefficients closed . map unpack $ ps
cubicSpline closed ps = flattenBeziers . map f . solveCubicSplineCoefficients closed . map unPoint $ ps
where
f [a,b,c,d] = [a, (3*a+b)/3, (3*a+2*b+c)/3, a+b+c+d]
flattenBeziers bs@((b:_):_)
Expand Down
31 changes: 15 additions & 16 deletions src/Diagrams/Path.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module Diagrams.Path

-- * Paths

Path(..)
Path, pathTrails

-- * Constructing paths
-- $construct
Expand Down Expand Up @@ -67,7 +67,7 @@ import Diagrams.TrailLike
import Diagrams.Transform

import Control.Arrow ((***))
import Control.Newtype hiding (under)
import Control.Lens (Iso, from, iso, mapped, over, view, (%~))
import Data.AffineSpace
import qualified Data.Foldable as F
import Data.List (partition)
Expand All @@ -82,21 +82,20 @@ import Data.VectorSpace
-- Hence, unlike trails, paths are not translationally invariant,
-- and they form a monoid under /superposition/ (placing one path on
-- top of another) rather than concatenation.
newtype Path v = Path { pathTrails :: [Located (Trail v)] }
newtype Path v = Path { _pathTrails :: [Located (Trail v)] }
deriving (Semigroup, Monoid)

pathTrails :: Iso (Path v) (Path v') [Located (Trail v)] [Located (Trail v')]
pathTrails = iso _pathTrails Path

deriving instance Show v => Show (Path v)
deriving instance Eq v => Eq (Path v)
deriving instance Ord v => Ord (Path v)

type instance V (Path v) = v

instance Newtype (Path v) [Located (Trail v)] where
pack = Path
unpack = pathTrails

instance VectorSpace v => HasOrigin (Path v) where
moveOriginTo = over Path . map . moveOriginTo
moveOriginTo = over pathTrails . map . moveOriginTo

-- | Paths are trail-like; a trail can be used to construct a
-- singleton path.
Expand All @@ -106,7 +105,7 @@ instance (InnerSpace v, OrderedField (Scalar v)) => TrailLike (Path v) where
-- See Note [Transforming paths]
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v))
=> Transformable (Path v) where
transform = over Path . map . transform
transform = over pathTrails . map . transform

{- ~~~~ Note [Transforming paths]

Expand All @@ -121,7 +120,7 @@ of the v's are inside Points and hence ought to be translated.
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v)) => IsPrim (Path v)

instance (InnerSpace v, OrderedField (Scalar v)) => Enveloped (Path v) where
getEnvelope = F.foldMap trailEnvelope . pathTrails
getEnvelope = F.foldMap trailEnvelope . view pathTrails
-- this type signature is necessary to work around an apparent bug in ghc 6.12.1
where trailEnvelope :: Located (Trail v) -> Envelope v
trailEnvelope (viewLoc -> (p, t)) = moveOriginTo ((-1) *. p) (getEnvelope t)
Expand Down Expand Up @@ -166,11 +165,11 @@ pathFromLocTrail = trailLike
-- | Extract the vertices of a path, resulting in a separate list of
-- vertices for each component trail (see 'trailVertices').
pathVertices :: (InnerSpace v, OrderedField (Scalar v)) => Path v -> [[Point v]]
pathVertices = map trailVertices . pathTrails
pathVertices = map trailVertices . view pathTrails

-- | Compute the total offset of each trail comprising a path (see 'trailOffset').
pathOffsets :: (InnerSpace v, OrderedField (Scalar v)) => Path v -> [v]
pathOffsets = map (trailOffset . unLoc) . pathTrails
pathOffsets = map (trailOffset . unLoc) . view pathTrails

-- | Compute the /centroid/ of a path (/i.e./ the average location of
-- its vertices).
Expand All @@ -179,18 +178,18 @@ pathCentroid = centroid . concat . pathVertices

-- | Convert a path into a list of lists of 'FixedSegment's.
fixPath :: (InnerSpace v, OrderedField (Scalar v)) => Path v -> [[FixedSegment v]]
fixPath = map fixTrail . unpack
fixPath = map fixTrail . view pathTrails

-- | \"Explode\" a path by exploding every component trail (see
-- 'explodeTrail').
explodePath :: (VectorSpace (V t), TrailLike t) => Path (V t) -> [[t]]
explodePath = map explodeTrail . pathTrails
explodePath = map explodeTrail . view pathTrails

-- | Partition a path into two paths based on a predicate on trails:
-- the first containing all the trails for which the predicate returns
-- @True@, and the second containing the remaining trails.
partitionPath :: (Located (Trail v) -> Bool) -> Path v -> (Path v, Path v)
partitionPath p = (pack *** pack) . partition p . unpack
partitionPath p = (view (from pathTrails) *** view (from pathTrails)) . partition p . view pathTrails

------------------------------------------------------------
-- Modifying paths ---------------------------------------
Expand All @@ -204,4 +203,4 @@ scalePath d p = (scale d `under` translation (origin .-. pathCentroid p)) p

-- | Reverse all the component trails of a path.
reversePath :: (InnerSpace v, OrderedField (Scalar v)) => Path v -> Path v
reversePath = (over Path . map) reverseLocTrail
reversePath = pathTrails . mapped %~ reverseLocTrail
7 changes: 3 additions & 4 deletions src/Diagrams/Points.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ module Diagrams.Points

import Diagrams.Core.Points

import Control.Newtype

import Control.Arrow ((&&&))
import Control.Arrow ((&&&))

import Data.AffineSpace.Point
import Data.VectorSpace

-- | The centroid of a set of /n/ points is their sum divided by /n/.
centroid :: (VectorSpace v, Fractional (Scalar v)) => [Point v] -> Point v
centroid = pack . uncurry (^/) . (sumV &&& (fromIntegral . length)) . map unpack
centroid = P . uncurry (^/) . (sumV &&& (fromIntegral . length)) . map unPoint
45 changes: 22 additions & 23 deletions src/Diagrams/ThreeD/Types.hs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE ViewPatterns #-}

{-# OPTIONS_GHC -fno-warn-orphans #-}

Expand Down Expand Up @@ -39,17 +39,17 @@ module Diagrams.ThreeD.Types
, asSpherical
) where

import Control.Applicative
import Control.Applicative
import Control.Lens (Iso', iso, over)

import Diagrams.Coordinates
import Diagrams.TwoD.Types
import Diagrams.Core
import Diagrams.Coordinates
import Diagrams.Core
import Diagrams.TwoD.Types

import Control.Newtype

import Data.Basis
import Data.VectorSpace
import Data.Cross
import Data.AffineSpace.Point
import Data.Basis
import Data.Cross
import Data.VectorSpace

------------------------------------------------------------
-- 3D Euclidean space
Expand All @@ -58,23 +58,22 @@ import Data.Cross
newtype R3 = R3 { unR3 :: (Double, Double, Double) }
deriving (AdditiveGroup, Eq, Ord, Show, Read)

instance Newtype R3 (Double, Double, Double) where
pack = R3
unpack = unR3
r3Iso :: Iso' R3 (Double, Double, Double)
r3Iso = iso unR3 R3

-- | Construct a 3D vector from a triple of components.
r3 :: (Double, Double, Double) -> R3
r3 = pack
r3 = R3

-- | Convert a 3D vector back into a triple of components.
unr3 :: R3 -> (Double, Double, Double)
unr3 = unpack
unr3 = unR3

type instance V R3 = R3

instance VectorSpace R3 where
type Scalar R3 = Double
(*^) = over R3 . (*^)
(*^) = over r3Iso . (*^)

instance HasBasis R3 where
type Basis R3 = Either () (Either () ()) -- = Basis (Double, Double, Double)
Expand All @@ -98,11 +97,11 @@ type P3 = Point R3

-- | Construct a 3D point from a triple of coordinates.
p3 :: (Double, Double, Double) -> P3
p3 = pack . pack
p3 = P . R3

-- | Convert a 2D point back into a triple of coordinates.
unp3 :: P3 -> (Double, Double, Double)
unp3 = unpack . unpack
unp3 = unR3 . unPoint

-- | Transformations in R^3.
type T3 = Transformation R3
Expand Down
13 changes: 7 additions & 6 deletions src/Diagrams/TwoD/Offset.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ module Diagrams.TwoD.Offset
) where

import Control.Applicative
import Control.Lens (view)

import Data.AffineSpace
import Data.Monoid
Expand Down Expand Up @@ -232,9 +233,9 @@ offsetTrail = offsetTrail' def

-- | Offset a 'Path' by applying 'offsetTrail'' to each trail in the path.
offsetPath' :: OffsetOpts -> Double -> Path R2 -> Path R2
offsetPath' opts r = mconcat
. map (bindLoc (trailLike . offsetTrail' opts r) . (`at` origin))
. pathTrails
offsetPath' opts r = mconcat
. map (bindLoc (trailLike . offsetTrail' opts r) . (`at` origin))
. view pathTrails

-- | Offset a 'Path' with the default options and given radius. See 'offsetPath''.
offsetPath :: Double -> Path R2 -> Path R2
Expand Down Expand Up @@ -349,9 +350,9 @@ expandTrail = expandTrail' def

-- | Expand a 'Path' using 'expandTrail'' on each trail in the path.
expandPath' :: ExpandOpts -> Double -> Path R2 -> Path R2
expandPath' opts r = mconcat
. map (bindLoc (expandTrail' opts r) . (`at` origin))
. pathTrails
expandPath' opts r = mconcat
. map (bindLoc (expandTrail' opts r) . (`at` origin))
. view pathTrails

-- | Expand a 'Path' with the given radius and default options. See 'expandPath''.
expandPath :: Double -> Path R2 -> Path R2
Expand Down
11 changes: 6 additions & 5 deletions src/Diagrams/TwoD/Path.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ module Diagrams.TwoD.Path
) where

import Control.Applicative (liftA2)
import Control.Lens (view, (^.))
import qualified Data.Foldable as F
import Data.Semigroup
import Data.Typeable
Expand Down Expand Up @@ -80,7 +81,7 @@ instance Traced (Trail R2) where
. lineSegments

instance Traced (Path R2) where
getTrace = F.foldMap getTrace . pathTrails
getTrace = F.foldMap getTrace . view pathTrails

------------------------------------------------------------
-- Constructing path-based diagrams ----------------------
Expand Down Expand Up @@ -112,9 +113,9 @@ instance Renderable (Path R2) b => TrailLike (QDiagram b R2 Any) where
-- ... }@ syntax may be used.
stroke' :: (Renderable (Path R2) b, IsName a) => StrokeOpts a -> Path R2 -> Diagram b R2
stroke' opts path
| null (pathTrails pLines) = mkP pLoops
| null (pathTrails pLoops) = mkP pLines
| otherwise = mkP pLines <> mkP pLoops
| null (pLines ^. pathTrails) = mkP pLoops
| null (pLoops ^. pathTrails) = mkP pLines
| otherwise = mkP pLines <> mkP pLoops
where
(pLines,pLoops) = partitionPath (isLine . unLoc) path
mkP p
Expand Down Expand Up @@ -282,7 +283,7 @@ isInsideEvenOdd p = odd . crossings p
-- | Compute the sum of /signed/ crossings of a path as we travel in the
-- positive x direction from a given point.
crossings :: P2 -> Path R2 -> Int
crossings p = F.sum . map (trailCrossings p) . pathTrails
crossings p = F.sum . map (trailCrossings p) . view pathTrails

-- | Compute the sum of signed crossings of a trail starting from the
-- given point in the positive x direction.
Expand Down
3 changes: 2 additions & 1 deletion src/Diagrams/TwoD/Shapes.hs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import Diagrams.TwoD.Types

import Diagrams.Util

import Control.Lens (view)
import Data.Default.Class
import Data.Semigroup

Expand Down Expand Up @@ -105,7 +106,7 @@ square d = rect d d
--
-- <<diagrams/src_Diagrams_TwoD_Shapes_rectEx.svg#diagram=rectEx&width=150>>
rect :: (TrailLike t, Transformable t, V t ~ R2) => Double -> Double -> t
rect w h = trailLike . head . pathTrails $ unitSquare # scaleX w # scaleY h
rect w h = trailLike . head . view pathTrails $ unitSquare # scaleX w # scaleY h

-- > rectEx = rect 1 0.7 # pad 1.1

Expand Down