Haskell 中的多项式

发布于 2024-12-02 02:48:14 字数 1147 浏览 0 评论 0原文

周四我有一场关于函数式编程的考试,我很确定我必须用多项式做 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]

非常感谢!

I have an exam on thursday about Functional programming and I’m pretty sure that I will have to do a TAD with Polynomials. I’m adding polynomials for the moment like this:

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))

It perfectly works but the teacher doesn’t like. She prefers to do it with:

data Pol = P [(Int,Int)] deriving Show

At the beginning, I though it would be easy to change the structure but it’s not as I’m getting a lot of trouble in the compilation. Can anyone help me please? I tried this way but it doesn’t work:

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)))

I get this error:

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]

Thank you so much!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一身骄傲 2024-12-09 02:48:14

如果某些事情不起作用,请在问题中解释原因。如果有编译器错误,请发布。

在本例中,问题是 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)。其他情况也有类似的错误。

If something doesn't work, please explain why in the question. If there are compiler errors, please post them.

In this case, the problem is a type error in the last branches of suma. Look at

suma (P ((c1,g1):xs)) (P ((c2,g2):ys))
    | g1 == g2  = P ((c1+c2,g1):suma (P xs) (P ys))

In P ((c1+c2,g1):suma (P xs) (P ys)), you're trying to create a list of type [(Int,Int)] with

(c1+c2,g1):suma (P xs) (P ys)

You're trying to construct a list with the head at type (Int,Int), but the tail at type Pol (the result type of suma). The other cases have similar errors.

若水微香 2024-12-09 02:48:14

让 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)

如果你想要更时尚或更单子 :) 那么你可以让 Pol 成为单子并使用 do 表示法来做这些事情

Make suma to work on List such that:

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))

Then Sum for Pol can be defined as:

sumPol :: Pol -> Pol -> Pol
sumPol (P a) (P b) = P (suma a b)

In case you want to be more stylish or monadic :) then you can make Pol a monad and use a do notation to do the stuff

夢归不見 2024-12-09 02:48:14

首先,让我们考虑一下您的原始代码

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 吗语法?我认为它可以简化你的工作并使事情变得清晰。这里有一个提示:

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}]}

多项式的简化有点棘手,但这是一个很好的练习。

我希望这有帮助。

First of all, let's consider your original code

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))

If you do:

let p1 = [(5,0),(1,1),(7,2)]::Pol
let p2 = [(1,2),(3,1),(2,0)]::Pol

then you get:

suma p1 p2
[(1,2),(3,1),(7,0),(1,1),(7,2)]

This is not "wrong", but it's not what one may expect out of summing two polynomials: you may want to get the result in its simplified form:

[(7,0),(4,1),(8,2)]

One more comment: have you learned about Haskell record syntax? I think it can simplify your work and make things cleared. Here's a hint:

data Term = Term { coeff :: Int,
                   expnt :: Int
                 } deriving Show

data Pol = Pol { terms :: [Term] } deriving Show

With that, summing two polynomials without simplifying the result is as simple as ... concatenating their terms :) ... and everything is showable:

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}]}

Simplification of a polynomial is a little trickier, but a good exercise.

I hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文