我正在实现一个小程序来处理多项式运算,其灵感来自于upenn cis194的一个赋值。代码如下(我省略了一些不相关的代码):
newtype Poly = Poly [Rational]
deriving Eq
s :: Poly
s = Poly [1, 0]
instance Num Poly where
(Poly a) + (Poly b) = ...
(Poly a) * (Poly b) = ...
negate (Poly xs) = ...
fromInteger i = Poly [fromInteger i]
instance Fractional Poly where
fromRational f = Poly [fromRational f]
instance Show Poly where
show (Poly a) = ...
pdiv :: Poly -> Poly -> (Poly, Poly)
pdiv (Poly a) (Poly b) = ...
cauer1 :: Poly -> Poly -> String
cauer1 a b =
let (q, r) = pdiv a b
in if r == 0 then (show q) else
(show q) ++ " + 1/(" ++ (cauer1 b r) ++ ")"
此代码有效。例如,我可以得到多项式结果的长除法,以便使用cauer1
函数制作Cauer 1形式电路。 (电路分析)
ghci > let a = Poly [1, 23%6, 10%3, 0] -- represents: s^3 + 23/6 s^2 + 10/3 s
ghci > let b = Poly [1, 3, 2]
ghci > cauer1 a b
"s + 1/(6%5 + 1/(25%42s + 1/(49%5 + 1/(1%14s))))"
我现在要做的是做这样的事情:
ghci > cauer1 (s^3 + 23%6*s^2 + 10%3*s) (s^2 + 3*s + 2)
并获得相同的结果。
在制作Poly
Poly [Double]
和Poly
实例并实施Num
和{后,我的Fractional
类型定义为fromInteger
{1}},我可以执行fromRational
,s * 1
,s * 2.3
之类的操作,然后强大的类型类会将它们计算为3.4 * s^2
而没有任何问题。但是通过这种方式,结果是所有小数和丢失精度,这就是我切换到Poly
的原因。但现在我无法做Poly [Rational]
,他们只是根据ghc键入不匹配:
3%2 * s
我发现<interactive>:1:9:
Couldn't match expected type ‘Ratio a’ with actual type ‘Poly’
In the second argument of ‘(*)’, namely ‘s’
In the expression: (3 % 2) * s
是Rational
而Ratio Integer
是Ratio
和Num
的实例,为什么这不起作用,我该如何修复它?
答案 0 :(得分:1)
我可以执行类似
的操作s * 1
,s * 2.3
,3.4 * s^2
...
是的,因为(引用Prelude文档):
浮动文字表示将
fromRational
应用于Rational
类型的值,因此此类文字的类型为(Fractional a) => a
。
..这意味着您可以在任何地方使用Poly
(作为Fractional
的子类)
同样的举例不适用于3%2
,这不是文字,而是类型Integral a => Ratio a
的表达式,这只表示我可以在任何地方使用这样的表达式我可以使用Ratio a
(提供a
是Integral
)。这远没那么灵活。
然后,您需要的是一个运算符%
,3%2
将获得一个(Fractional a) => a
类型,就像文字3.14
这可以通过重新定义来完成,如下例
import qualified Data.Ratio as R
(%) :: Fractional a => Integer -> Integer -> a
x % y = fromRational ((R.%) x y)
-- the rest as in your example
现在你可以做到
*YourExample> :t 3%2 * s -- ask ghci whether this makes sense ...
3%2 * s :: Poly -- yes, it does!