在Haskell中表示多项式:
newtype Poly a = P [a]
x :: Num a => Poly a
x = P [1]
instance (Num a, Eq a) => Eq (Poly a) where
E.g。 P[1,2,3] = 3x^2 + 2x + 1
我想说两个多项式是相等的,如果它们具有相同的列表(例如P[1,2,3]
等于P[1,2,3]
)。如果列表相同,则它们也是相同的,除了最后一个元素是0'(例如P[1,2,3]
等于P[1,2,3,0,0]
)。
但是,我不知道如何执行此操作的语法。
答案 0 :(得分:4)
Eq
只需延伸Jakes的答案,就可以得到一个完整的答案:
我喜欢删除前导零的想法,然后你很快就会结束:
newtype Poly a = P [a]
instance (Num a, Eq a) => Eq (Poly a) where
P xs == P ys =
removeLeadingZeros (reverse xs) == removeLeadingZeros (reverse ys)
removeLeadingZeros :: (Eq a, Num a) => [a] -> [a]
removeLeadingZeros (0 : xs) = removeLeadingZeros xs
removeLeadingZeros xs = xs
请注意,您不必再次reverse
来寻找平等(xs == ys <=> reverse xs == reverse ys
)
这是ghci中的简短测试会话:
λ> let p1 = P[1,2,3,0,0]
λ> let p2 = P[1,2,3]
λ> let p3 = P[1,2,3,0,4]
λ> p1 == p2
True
λ> p1 == p3
False
λ> p2 == p3
False
另一种可能性是不发布P
构造函数并在构造时将多项式转换为规范化形式 - 这样做的好处是可以使用deriving Eq
module Poly
( Poly, fromList
) where
newtype Poly a = P [a]
deriving Eq
fromList :: (Num a, Eq a) => [a] -> Poly a
fromList = P . reverse . removeLeadingZeros . reverse
λ> let p1 = fromList [1,2,3,0,0]
λ> let p2 = fromList [1,2,3]
λ> p1 == p2
True
由于您似乎已经实现了Num (Poly a)
,您甚至可以从导出中删除fromList
- 因此用户必须使用算术运算符来构造多项式。
您基本上只需要导出x
:
x :: (Eq a, Num a) => Poly a
x = fromList [0,1]
取决于P []
是否适用于零多项式,或者在这种情况下您更愿意使用P [0]
,而您可能希望将removeLeadingZeros
重写为
removeLeadingZeros :: (Eq a, Num a) => [a] -> [a]
removeLeadingZeros [0] = [0]
removeLeadingZeros (0 : xs) = removeLeadingZeros xs
removeLeadingZeros xs = xs
或类似的东西
答案 1 :(得分:2)
removeLeadingZeros (0 : xs) = removeLeadingZeros xs
removeLeadingZeros xs = xs
反转列表,删除前导零,然后再反转。
(reverse . removeLeadingZeros . reverse) [3, 2, 1, 0, 0, 0]
对两个多项式执行相同的操作,并使用==
进行比较。
(暂不考虑,但我认为这是对的。)