2

我正在尝试使用 Haskell Diagrams 制作我自己的函数,该函数将两个图表水平/垂直相邻放置(如 ||| 或 ===),但它们之间有一个空格。如果我尝试这样做,我会得到错误:非法方程约束 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 (===)

如果有人能帮助我解决这个问题,我将不胜感激。

4

1 回答 1

3

有几个问题。

  1. 正如您的代码给出的错误所说,您需要启用GADTsorTypeFamilies语言扩展以使用类型相等约束(提到的那些~)。
  2. 您的语法不太正确:(===) emptyBlock (===)试图将两个“图表”放在emptyBlock彼此(===)之上。由于(===)不是图表,而是形成图表的功能,所以这不会飞。你应该写

    x ==== y = x === emptyBlock === y
    

    反而。

  3. 您声称(||||)(====)适用于任何可并列的图表,但它的实现包括一个白色矩形,这意味着它必须是可以设置样式、有轨迹并且可以转换的东西。更改类型签名行如下:

    (||||), (====) :: (Juxtaposable a, V a ~ R2, Semigroup a, TrailLike a, HasStyle a, Transformable a) => a -> a -> a
    

    (或者,如果您打算禁用单态限制,则可能完全省略它。)

  4. 你没有给出类型签名,它是类型类多态的,所以单态限制开始了。给它一个类型签名,或者通过启用语言扩展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

但是,这仍然有一些不足之处:

  • 如果您使用它来分隔顶部不是白色的图表,则仍将绘制分隔符,可能会使底层图表的某些部分黯然失色。
  • 矩形在二维中扩展,这意味着如果您使用它来水平对齐比您的间隔短的图表或垂直对齐比您的间隔窄的图表,生成的合成将有一个不正确的包络。

您可以使用strutXandstrutY而不是emptyBlock. 这也将更笼统:您不需要包含看起来很奇怪的可样式化/可转换约束。这种方法的一个例子是:

x ==== y = x === strutY 1 === y
x |||| y = x ||| strutX 3 ||| y
于 2014-05-25T02:14:35.333 回答