Reputation: 71
I'm trying use Haskell Diagrams to make my own function which places two diagrams horizontally/vertically adjacent to one another (like ||| or ===) but with a space between them. If I try to do like this, I get error: Illegal equational constraint V a ~ R2
emptyBlock = rect (3) (1) # fc white # lc white
(||||) :: (Juxtaposable a, V a ~ R2, Semigroup a) => a -> a -> a
(||||) = (|||) emptyBlock (|||)
(====) :: (Juxtaposable a, V a ~ R2, Semigroup a) => a -> a -> a
(====) = (===) emptyBlock (===)
I would be very thankful if anyone could help me to fix this problem.
Upvotes: 2
Views: 235
Reputation: 152837
There are several problems.
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.)
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:
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
Upvotes: 3