From HaskellWiki
< Diagrams‎ | Dev
Jump to navigation Jump to search

This page describes breaking API changes between diagrams 1.2 and 1.3, along with explanations of how to migrate to the new 1.3 API.

The 1.3 release includes a lot of new features and reorganization; there are surely to be breaking changes that we missed below. Please ask on the diagrams mailing list or IRC channel for help migrating to 1.3, and feel free to edit this page with additional information or better explanations as you upgrade.


Diagrams has switched from vector-space to linear for its linear algebra package. This makes many things nicer, and in particular allows diagrams to now be polymorphic over the underlying numeric type, potentially paving the way for things like automatic differentiation. It does, however, mean that many types are now slightly different.

The most obvious difference is there are now two type variables for the vector space: v, which gives the space being worked in and n, the number type used. v now has kind * -> *, which means is takes some type (usually n) and makes a concrete vector. Basically this means whenever you saw v, replace it by v n. So:

  • R2 -> V2 Double
  • Point R2 (P2) -> Point V2 Double (P2 Double)
  • Path R2 -> Path V2 Double
  • Transformation R2 -> Transformation V2 Double (T2 Double)
  • QDiagram b v m -> QDiagram b v n m

The Diagram alias has also changed. It no longer takes a vector space as a parameter; it simply uses the default space and number type for the backend parameter:

Diagram b = QDiagram b (V b) (N b) Any

where V b is the default space and N b is the default number type for backend b. This means you should replace e.g.

  • Diagram Cairo R2 -> Diagram Cairo

Scalar also no longer exists; you should replace

  • Scalar -> N

linear’s functions are very similar to vector-space. The biggest difference is lerp which is defined as

lerp alpha u v = alpha *^ u ^+^ (1 - alpha) *^ v

This is the opposite way round to vector-space’s lerp.

Other changes from vector-space to linear:

  • magnitude -> norm
  • magnitudeSq -> quadrance
  • negateV -> negated
  • normalized -> signorm

The last is particularly worth noting, since there is also a new normalized function (which constructs Measure values). So code which used normalized, instead of yielding a "not in scope" error, will yield a type error, probably something along the lines of

Couldn't match type ‘Measured n0 n0’ with ‘V2 Double’

The old HasX, HasY and HasZ classes have been replaced by linear’s R1, R2 and R3, but these have lenses of the same names (_x, _y, _z) so you probably won't notice the difference.

Direction type

A new Direction type has been added to Diagrams.Direction. A Direction is a vector that has forgot its magnitude. Certain functions including arc and reflectAcross have had their types moved from V2 Double to Direction Double to make it clear the magnitude has no impact.

arc now takes a starting direction and an angle. arcCW and arcCCW give a clockwise or counter clockwise arc between two directions. For example, if you had

arc (0 @@ turn) (1/3 @@ turn)

you should replace it by

arc xDir (1/3 @@ turn)

As another example,

arc (1/3 @@ turn) (2/3 @@ turn)

can be replaced by

arc (angleDir (1/3 @@ turn)) (1/3 @@ turn)

angleBetween is commutative (and always positive). We also introduced signedAngleBetween which reflects a (counterclockwise) ordering on angles.

rotateAbout used to rotate about a point in 2D; it now rotates about a line in 3D. The old rotateAbout has been replaced by rotateAround.

Measure changes

The internal representation of Measure has now changed. The old constructors cannot be used anymore. Instead they have been replaced by:

  • Normalized -> normalized or normalised
  • Local -> local
  • Global -> global
  • Output -> output


SizeSpec2D is now SizeSpec V2 Double and has moved to Diagrams.Size. The resizing functions now work for any vector space. The constructors have been replaced with the following functions:

  • Dims -> dims2D
  • Width -> mkWidth
  • Height -> mkHeight
  • Absolute -> absolute

dims2D, mkWidth and mkHeight are in Diagrams.TwoD.Size.

mkSizeSpec used to be specific to 2D; it is now generic over any vector space. Use mkSizeSpec2D instead.


The qualify with name operator (|>) has moved to (.>>) to make room for lens's snoc operator (|>) (which now works on Lines).

Transform isomorphisms

New transform isomorphisms transformed, translated, movedTo, movedFrom and rotated have been added. These can be used with lens’s under function (see Diagrams.Transform for usage examples). The old under has been renamed to underT.

ToPath class

A new ToPath class has been added. It takes path-like things (like lines, loops, trails, paths) and converts them to a Path.

This is very different from the TrailLike class, which is polymorphic in it’s result. Because both these classes are polymorphic, you can’t produce something with the TrailLike class and consume it with ToPath without specifying the type in between.

Because stroke now uses this class it can cause some ambiguity errors for old code. The old (less polymorphic) stroke has moved to strokePath (or strokeP).

fsnotify for command line loop

The --loop option for diagrams command line generation uses fsnotify to watch the source file for changes. This means it should now work on Windows.

Additionally it now works in sandboxes and has a cleaner terminal output.


diagrams-svg no longer depends on the blaze.svg package and instead uses lucid-svg.

The only difference that should affect diagrams code is that the SVGOptions record has changed from:

SVGOptions {_size :: SizeSpec2D, _svgDefinitions :: Maybe S.Svg}


SVGOptions { _size :: SizeSpec V2 n, _svgDefinitions :: Maybe SvgM, _idPrefix :: T.Text} .

New features

Segment intersections have been added to Diagrams.TwoD.Segment. Functions for intersection points of path-like things are in Diagrams.TwoD.Path.

There’s a function for finding the convex hull for a list of 2D points in Diagrams.TwoD.Points.

Affine maps have been added to Diagrams.LinearMap that can map between spaces. The Deformable class has also been generalised to map between spaces. Helper functions have been added to Diagrams.ThreeD.Projection for basic orthographic and perspective projections. These can’t be used on a Diagram yet be can be used on path-like things.

Some extra functions have been added to Diagrams.Model to help visualise the Trace and Envelope of a diagram.

New Backends

PGF backend

PGF is tex a macro package for creating graphics. It’s the low level backend for TikZ.

The diagrams-pgf backend supports most of diagrams’ features including paths, images (external and embedded), gradients (partial support) and text. It also includes an experimental functions for retrieving the size of the bounding boxes for text (including formulas). See the examples page for more details.

It uses texrunner to produce PDF files and parse tex’s output. Latex, Context and plain Tex outputs are supported.

HTML5 backend

The diagrams-html5 backend supports most of diagrams’ features including paths, external images , gradients and text. It produces standalone javascript code.


The most important functions for use in diagrams textSVG' and testSVG_ have been move out of the ReadFont module into the Text module. You can usually just import Graphics.SVGFonts and have all of the functions you need.

textSVG' and friends now have the text as a separate argument, distinct from TextOptions. So whereas before you might write:

textSVG' (TextOpts s lin2 INSIDE_H KERN False d d)

now you would write:

textSVG' (TextOpts lin2 INSIDE_H KERN False d d) s.


  • LineWidth and Dashing has moved back to Diagrams.Attributes.
  • There is no longer a Diagrams.Prelude.ThreeD. Instead all functions are exported by Diagrams.Prelude and functions have had their types generalised to the R1, R2 and R3 classes.
  • Control.Lens and Data.Default are now exported from Diagrams.Prelude. Some names from Control.Lens were hidden.
  • A new Diagrams module now only exports functions defined in the diagrams library.
  • Diagrams.TwoD.Transform.ScaleInv has moved to Diagrams.Transform.ScaleInv.