2

事实证明,annularWedge图表包的功能不能将半径设为 0 作为内半径。您必须wedge改用。

对我来说,0 的内半径只是退化的情况,annularWedge并且应该表现得像wedge,所以我尝试将它们组合起来:

mywedge r2 r1 d a
  | r1 == 0   = wedge r2 d a
  | otherwise = annularWedge r2 r1 d a

当然,它不起作用,我无法弄清楚错误的含义:

Non type-variable argument in the constraint: RealFloat (N t)
(Use FlexibleContexts to permit this)
When checking that ‘mywedge’ has the inferred type
  mywedge :: forall t.
             (RealFloat (N t), TrailLike t, V t ~ V2) =>
             N t -> N t -> Direction V2 (N t) -> Angle (N t) -> t

事实上,事实证明,annularWedge并且wedge有不同的约束,这让我很惊讶:

annularWedge :: (TrailLike t, V t ~ V2, N t ~ n, RealFloat n) => n -> n -> Direction V2 n -> Angle n -> t

wedge :: (InSpace V2 n t, OrderedField n, TrailLike t) => n -> Direction V2 n -> Angle n -> t

那么如何将这两个函数组合成一个接受内半径为 0 并做正确事情的理智函数呢?

4

2 回答 2

3

解决方案很简单。正如 ErikR 所说,添加{-# LANGUAGE FlexibleContexts, TypeFamilies #-}到文件的顶部。需要明确的是,这些都是可以添加的安全扩展(某些扩展,如重叠实例或不可判定的实例应该让您在启用它们之前暂停,但这些扩展大多是安全的)

虽然不是很明显,但wedge签名的约束严格地弱于annularWedges 的约束。

如果您对为什么签名看起来如此不同感到好奇,请继续阅读...

对于初学者来说,一旦你找到约束,它们并没有什么不同。让我们从wedge.

(InSpace V2 n t, OrderedField n, TrailLike t)

查看 的定义InSpace,你会发现它没有任何功能,它本质上就像一个同义词:(V a ~ v, N a ~ n, Additive v, Num n) => InSpace v n a。然后,我们可以展开InSpace V2 n t(V t ~ V2, N t ~ n, Additive V2, Num n)。同样,OrderedField原来只是 的简写(Floating n, Ord n)。现在,约束wedge看起来像

(TrailLike t, V t ~ V2, N t ~ n, Additive V2, Num n, Floating n, Ord n)

然而,事实证明我们甚至可以放弃Additive V2约束,因为该实例是在定义的地方Additive定义的,Linear.Vector并且Num n是多余的,假设Num n => Fractional n => Floating n. 这给我们留下了更简单的约束wedge

(TrailLike t, V t ~ V2, N t ~ n, Floating n, Ord n)

这看起来很像annularWedge. 实际上,唯一的区别是Constrains与wedgeconstraining(Floating n, Ord n)相比。在这一点上,约束非常相似,值得研究. 事实证明,使用, defined in和相应的实例使用反正切函数(在追逐更多依赖项后得到)。annularWedgeRealFloat nwedgewedge_thetaHasThetaV2

于 2016-08-08T20:00:44.957 回答
2

只需遵循 GHC 给您的建议:

{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}

import Diagrams
import Diagrams.TwoD.Arc

mywedge r2 r1 d a
  | r1 == 0   = wedge r2 d a
  | otherwise = annularWedge r2 r1 d a

不过,总的来说,我更喜欢<=在处理浮点数时使用比较,例如:

  | r1 <= 1e-10 = wedge r2 d 1
于 2016-08-08T19:50:12.150 回答