1

我希望能够通过首先按长度(度)比较,其次按系数比较来订购多项式。多项式是带有 的双精度列表[1,2,3] = 3x²+2x+1。但是如果最后一个元素是零,它应该被删除,所以我写了一个函数来做这件事,叫做realPolynom. realPolynom [1,2,3,0] = [1,2,3] 现在,我的 Ord 实例如下所示:

instance Ord Polynom where                                  
    compare a b = compare ((realLength a), reverse (pol2list (realPolynom a))) ((realLength b), reverse (pol2list (realPolynom b)))

realLength只是最后一个没有零的多项式的长度。

pLength :: Polynom -> Int       
pLength (Polynom(a)) = length a

realLength :: Polynom -> Int                        
realLength a = pLength(realPolynom(a))

pol2listPolynom p = p

pol2list :: Polynom -> [Double]
pol2list (Polynom p) = p 

问题是:

  • [0,2,0] < [0,2,3]真的,这很好

  • [0,2,0] < [0,2]假的,也不错

  • [0,2,0] > [0,2]假的,也不错

  • [0,2,0] == [0,2]假的,不好!应该是平等的!

4

3 回答 3

7

而不是推导 Eq,你可能应该写

instance Eq Polynom where
  a == b = compare a b == EQ
于 2014-05-19T12:52:12.227 回答
4

最好的解决方案可能是确保一开始就不会出现前导零。也就是说,您不必从列表中手动构建多项式,而是将它们提供给“智能构造函数”,该构造函数在打包Polynome数据类型之前会吃掉零。

可能看起来有点面向对象的事情,但有时这种封装只是要走的路,即使在函数式语言中也是如此。

于 2014-05-19T12:58:36.550 回答
0

像这样的东西应该工作:

instance Eq Polynom where
    x == y = pol2list (realPolynom x) == pol2list (realPolynom y)

不幸的是,在这种情况下,派生Eq实例不是预期的实例。

于 2014-05-19T12:52:39.377 回答