我想我会尝试造型上不同维度的向量数量一定数值积分,并推断该类型的类是要走的路。我需要的东西由乘法器来定义两个值和缩放它之间的差(以获得衍生物),以及能够采取的距离函数。

到目前为止,我有:

class Integratable a where
    difference :: a -> a -> a
    scale :: Num b => a -> b -> a
    distance :: Num b => a -> a -> b

data Num a => Vector a = Vector1D a | Vector2D a a

instance Num a => Integratable (Vector a) where
    difference (Vector1D x1) (Vector1D x2) = Vector1D (x1 - x2)
    scale (Vector1D x) m = Vector1D (x * m)
    distance (Vector1D x1) (Vector1D x2) = x1 - x2
    difference (Vector2D x1 y1) (Vector2D x2 y2) = Vector2D (x1 - x2) (y1 - y2)
    scale (Vector2D x y) m = Vector2D (x * m) (y * m)
    distance (Vector2D x1 y1) (Vector2D x2 y2) = sqrt((x1-x2)*(x1-x2)
                                                      + (y1-y2)*(y1-y2))

不幸的是一对夫妇在这里的问题,我还没有想出如何解决。首先,scale函数给出错误。 GHC也说不清,因为刚性类型限制m在一个情况下,在实例因为xNum是兼容的,而在其他情况下,Vector型......有没有一种方法来指定xm是相同类型?

(我知道其实即使xm都是Num,他们可能不是的相同Num,我怎么可以指定这个吗?如果我不能Num弄明白,使用Double将被罚款,但我宁愿保持它一般。)

有一个类似的问题distance。试图指定的返回类型Num失败,因为它不能在a是要含有与b兼容值的实例定义出来。

有帮助吗?

解决方案

编辑:现在看来,我认为在函数依赖的文章从HaskellWiki提供了我能找到的最好形式的关键信息,所以我代替我的回答是,这里建议阅读。我不删除内容的其余部分,不过,因为它清楚(我希望)为什么文件描述符是有用的在这里。


除了定义问题的分组该戴夫指出...

  

(我知道其实即使xm都是Num,他们可能不是的相同Num,我怎么可以指定这个吗?如果我不能Num弄明白,使用Double将被罚款,但我宁愿保持它一般。)

这是主要的问题,实际上。你不能用Integer乘的Float,说。在效果上,你需要的x和规模m是相同类型的。

另外,一个类似的问题随着距离出现时,与附加的并发症,sqrt需要Floating参数。所以我想你需要提过那个地方。 (最有可能的情况下,我想)。

编辑:确定,因为sqrt只适用于Floating值,你可以滚类型类为那些上溯造型Floats到Doubles需要时

另一个想法涉及具有类型类Scalable

data Vector a = Vector1D a | Vector2D a a deriving (Show)                       

class Scalable a b | a -> b where
  scale :: a -> b -> a

instance (Num a) => Scalable (Vector a) a where
  scale (Vector1D x)   m = (Vector1D (x * m))
  scale (Vector2D x y) m = (Vector2D (x * m) (y * m))

此使用在Scalable定义一个所谓的功能依赖性。事实上,试图记住的语法,我发现此链接 ...所以我想你应该是有帮助的无视我不如尝试和读取品质的信息在那里。 ; - )

我想你应该可以用这个来解决原来的问题。

其他提示

要解决的第二个错误,我认为你需要重新排序实例声明的定义。第一有两个方程difference,则方程scale,则两个对distance

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top