我星期四有关于函数式编程的考试,我很确定我将不得不用多项式做一个TAD。我正在这样添加多项式:
type Pol = [(Int,Int)]
suma :: Pol -> Pol -> Pol
suma [] ys = ys
suma xs [] = xs
suma ((c1,g1):xs) ((c2,g2):ys)
| g1 == g2 = ((c1+c2,g1):(suma xs ys))
| g1 > g2 = ((c1,g1):(suma xs ((c2,g2):ys)))
| g1 < g2 = ((c2,g2):(suma ((c1,g1):xs) ys))
它完美有效,但老师不喜欢。她更喜欢这样做:
data Pol = P [(Int,Int)] deriving Show
一开始,我虽然很容易改变结构,但并不是因为我在编译中遇到了很多麻烦。有人可以帮我吗?我试过这种方式,但它不起作用:
data Pol = P [(Int,Int)] deriving Show
suma :: Pol -> Pol -> Pol
suma (P []) (P ys) = P ys
suma (P xs) (P []) = P xs
suma (P ((c1,g1):xs)) (P ((c2,g2):ys))
| g1 == g2 = P ((c1+c2,g1):suma (P xs) (P ys))
| g1 > g2 = P ((c1,g1):(suma (P xs) (P ((c2,g2):ys))))
| g1 < g2 = P ((c2,g2):(suma (P ((c1,g1):xs)) (P ys)))
我收到此错误:
ERROR file:.\Febrero 2011.hs:7 - Type error in application
*** Expression : P (c1 + c2,g1) : suma (P xs) (P ys)
*** Term : suma (P xs) (P ys)
*** Type : Pol
*** Does not match : [a]
非常感谢你!
答案 0 :(得分:3)
如果某些内容不起作用,请在问题中解释原因。如果有编译错误,请发布。
在这种情况下,问题是suma
的最后一个分支中的类型错误。看看
suma (P ((c1,g1):xs)) (P ((c2,g2):ys))
| g1 == g2 = P ((c1+c2,g1):suma (P xs) (P ys))
在P ((c1+c2,g1):suma (P xs) (P ys))
中,您尝试使用
[(Int,Int)]
的列表
(c1+c2,g1):suma (P xs) (P ys)
您正在尝试构建一个类型为(Int,Int)
的头部列表,但是类型为Pol
的尾部(结果类型为suma
)。其他案件也有类似的错误。
答案 1 :(得分:2)
让suma在List上工作:
suma :: [(Int,Int)] -> [(Int,Int)] -> [(Int,Int)]
suma [] ys = ys
suma xs [] = xs
suma ((c1,g1):xs) ((c2,g2):ys)
| g1 == g2 = ((c1+c2,g1):(suma xs ys))
| g1 > g2 = ((c1,g1):(suma xs ((c2,g2):ys)))
| g1 < g2 = ((c2,g2):(suma ((c1,g1):xs) ys))
然后Pol的Sum可以定义为:
sumPol :: Pol -> Pol -> Pol
sumPol (P a) (P b) = P (suma a b)
如果你想要更时尚或monadic :)那么你可以让Pol成为monad并使用do notation来做这些事情
答案 2 :(得分:0)
首先,让我们考虑您的原始代码
type Pol = [(Int,Int)]
suma :: Pol -> Pol -> Pol
suma [] ys = ys
suma xs [] = xs
suma ((c1,g1):xs) ((c2,g2):ys)
| g1 == g2 = ((c1+c2,g1):(suma xs ys))
| g1 > g2 = ((c1,g1):(suma xs ((c2,g2):ys)))
| g1 < g2 = ((c2,g2):(suma ((c1,g1):xs) ys))
如果你这样做:
let p1 = [(5,0),(1,1),(7,2)]::Pol
let p2 = [(1,2),(3,1),(2,0)]::Pol
然后你得到:
suma p1 p2
[(1,2),(3,1),(7,0),(1,1),(7,2)]
这不是“错误的”,但这并不是人们对两个多项式求和所期望的结果:你可能希望得到简化形式的结果:
[(7,0),(4,1),(8,2)]
还有一条评论:你了解了Haskell record syntax吗?我认为它可以简化您的工作并使事情得到澄清。这是一个提示:
data Term = Term { coeff :: Int,
expnt :: Int
} deriving Show
data Pol = Pol { terms :: [Term] } deriving Show
有了这个,在不简化结果的情况下求和两个多项式就像...连接它们的术语一样简单:) ......并且一切都可以显示:
Main> let p1 = Pol [Term 5 0, Term 1 1, Term 7 2]
Main> p1
Pol {terms = [Term {coeff = 5, expnt = 0},Term {coeff = 1, expnt = 1},Term {coeff = 7, expnt = 2}]}
Main> let p2 = Pol [Term 1 2, Term 3 1, Term 2 0]
Main> p2
Pol {terms = [Term {coeff = 1, expnt = 2},Term {coeff = 3, expnt = 1},Term {coeff = 2, expnt = 0}]}
Main> let p3 = sumpol p1 p2
Main> p3
Pol {terms = [Term {coeff = 5, expnt = 0},Term {coeff = 1, expnt = 1},Term {coeff = 7, expnt = 2},Term {coeff = 1, expnt = 2},Term {coeff = 3, expnt = 1},Term {coeff = 2, expnt = 0}]}
简化多项式有点棘手,但这是一个很好的练习。
我希望这会有所帮助。