我正在尝试使用Haskell图表来制作我自己的功能,该功能将两个图表水平/垂直相邻(如|||或===),但在它们之间有一个空间。如果我尝试这样做,我得到错误:非法方程约束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 (===)
如果有人能帮我解决这个问题,我将非常感谢。
有几个问题。
- 正如你的代码给出的错误所说,你需要启用
GADTs
或TypeFamilies
语言扩展来使用类型相等约束(提到~
的那些)。 -
您的语法不太正确:
(===) emptyBlock (===)
试图将两个"图表"emptyBlock
和(===)
放在彼此之上。因为(===)
不是一个图表,而是一个形成图表的函数,所以这不会飞。你应该写x ==== y = x === emptyBlock === y
。
-
你声称
(||||)
和(====)
适用于任何可并列的图表,但它的实现包括一个白色矩形,这意味着它必须是可以样式化的东西,有轨迹,可以转换。按如下方式更改类型签名行:(||||), (====) :: (Juxtaposable a, V a ~ R2, Semigroup a, TrailLike a, HasStyle a, Transformable a) => a -> a -> a
(或者,如果您打算禁用单态限制,可以完全省略它)
- 您没有给
emptyBlock
一个类型签名,而且它是类型类多态的,所以单态限制开始生效。给它一个类型签名,或者通过启用NoMonomorphismRestriction
语言扩展来关闭单态限制。
实现这四个更改会得到以下完整的文件:
{-# 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
然而,这仍然留下一些需要改进的地方:
- 如果您使用此分隔符来分隔位于非白色上方的图表,则仍然会绘制间隔符,可能会遮蔽底层图表的某些部分。
- 矩形在两个维度上扩展,这意味着如果您使用它来水平对齐比间隔条短的图表或垂直对齐比间隔条窄的图表,则生成的合成将具有不正确的包线。
你可以用strutX
和strutY
代替emptyBlock
来修复这两个问题。这也将更加通用:您不需要包含看起来奇怪的可样式/可转换约束。这种方法的一个例子是:
x ==== y = x === strutY 1 === y
x |||| y = x ||| strutX 3 ||| y