There are several problems.
- As the error your code gives says, you need to enable either the
GADTs
or TypeFamilies
language extension to use type equality constraints (the ones that mention ~
).
Your syntax isn't quite right: (===) emptyBlock (===)
is attempting to put the two "diagrams" emptyBlock
and (===)
above each other. Since (===)
isn't a diagram, but rather a function that forms diagrams, this isn't going to fly. You should write
x ==== y = x === emptyBlock === y
instead.
You claim that (||||)
and (====)
work for any juxtaposable diagrams, but its implementation includes a white rectangle, which means it has to be something that can be styled, has trails, and can be transformed. Change the type signature lines as follows:
(||||), (====) :: (Juxtaposable a, V a ~ R2, Semigroup a, TrailLike a, HasStyle a, Transformable a) => a -> a -> a
(Or, possibly, omit it entirely if you plan to disable the monomorphism restriction.)
- You haven't given
emptyBlock
a type signature, and it is typeclass polymorphic, so the monomorphism restriction kicks in. Give it a type signature, or turn off the monomorphism restriction by enabling the NoMonomorphismRestriction
language extension.
Implementing these four changes results in the following complete file:
{-# LANGUAGE NoMonomorphismRestriction, TypeFamilies #-}
import Diagrams.TwoD
import Data.Colour.Names
import Diagrams.Attributes
import Diagrams.Core
import Diagrams.Util
import Data.Semigroup
import Diagrams.TrailLike
emptyBlock = rect 3 1 # fc white # lc white
(||||), (====) :: (Juxtaposable a, V a ~ R2, Semigroup a, TrailLike a, HasStyle a, Transformable a) => a -> a -> a
x |||| y = x ||| emptyBlock ||| y
x ==== y = x === emptyBlock === y
However, this still leaves a few things to be desired:
- If you use this to separate diagrams that are over top something that isn't white, the spacer will still be drawn, potentially eclipsing some part of the underlying diagram.
- Rectangles extend in two dimensions, meaning that if you use this to horizontally align diagrams shorter than your spacer or vertically align diagrams narrower than your spacer, the resulting composite will have an incorrect envelope.
You can fix both of these things using strutX
and strutY
instead of emptyBlock
. This will also be more general: you won't need to include the odd-seeming stylable/transformable constraints. An example of this approach would be:
x ==== y = x === strutY 1 === y
x |||| y = x ||| strutX 3 ||| y