Function 我和Haskell有个错误,我找不到案子
因此,我试图创建这个函数AgregarMon,它基本上在Polinomio中添加了一个“Monomio” Monomio最终将成为Polinomio中的一个元素,Polinomio是一个列表。再过一会儿你就会明白了Function 我和Haskell有个错误,我找不到案子,function,haskell,recursion,switch-statement,haskell-prelude,Function,Haskell,Recursion,Switch Statement,Haskell Prelude,因此,我试图创建这个函数AgregarMon,它基本上在Polinomio中添加了一个“Monomio” Monomio最终将成为Polinomio中的一个元素,Polinomio是一个列表。再过一会儿你就会明白了 type Monomio = (Int, Int) type Polinomio = [Monomio] agregarMon :: Monomio -> Polinomio -> Polinomio agregarMon = \m p -> case m of{
type Monomio = (Int, Int)
type Polinomio = [Monomio]
agregarMon :: Monomio -> Polinomio -> Polinomio
agregarMon = \m p -> case m of{ (0,0) -> p;
x -> case p of{[] -> [x];
y:ys -> case (snd x == snd y) of { true -> case ((fst x + fst y)==0) of { true -> ys;
false -> (fst x + fst y , snd x):ys;}
false -> case snd x < snd y of{true -> y: agregarMon x ys;
false -> x:y:ys;}}}}
第45行是上面代码的第四行。对不起,如果我丢失了信息,请现在告诉我。
以防万一,有人不知道,fst和snd在前奏。fst从一个“Monomio”snd中获取第一个元素,并获取第二个元素。fst=(a,b)->a snd(a,b)->b虽然在必要时可以使用大括号和分号,但Haskell不是一种基于C的语言。它用于指示功能范围 类似这样的内容更为惯用:
agregarMon :: Monomio -> Polinomio -> Polinomio
agregarMon = \m p -> case m of
(0,0) -> p
x -> case p of
[] -> [x]
y:ys -> case (snd x == snd y) of
true -> case ((fst x + fst y)==0) of
true -> ys
false -> (fst x + fst y , snd x):ys
false -> case snd x < snd y of
true -> y: agregarMon x ys
false -> x:y:ys
agregarMon::Monomio->Polinomio->Polinomio
agregarMon=\m p->案例m
(0,0)->p
x->案例p
[]->[x]
y:ys->的情况(snd x==snd y)
正确->情况((fst x+fst y)==0)
对->Y
假->(fst x+fst y,snd x):ys
false->case snd xy:agregarMon x y
假->x:y:ys
这会编译(虽然有警告,请参见下文),但我不知道它是否符合您的要求。OP代码不编译,所以显然编译的东西是不等价的
然而,我所做的只是去掉所有的花括号和分号,而是“修复”缩进
在我看来,代码仍然太缩进,但至少(除了一个例外)它保留了80个字符。宽代码可能会迫使人们水平滚动,这不会让你交到很多朋友
上述代码在GHCi中加载,但带有警告:
[1 of 1] Compiling Q58986486 ( 58986486.hs, interpreted )
58986486.hs:14:49: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: false -> ...
|
14 | false -> (fst x + fst y , snd x):ys
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
58986486.hs:15:39: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: false -> ...
|
15 | false -> case snd x < snd y of
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
58986486.hs:17:49: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: false -> ...
|
17 | false -> x:y:ys
| ^^^^^^^^^^^^^^^
Ok, one module loaded.
[1/1]编译Q58986486(58986486.hs,已解释)
58986486.hs:14:49:警告:[-Woverlapping patterns]
模式匹配是多余的
在一种情况下,可选择:false->。。。
|
14 |假->(fst x+fst y,snd x):ys
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
58986486.hs:15:39:警告:[-Woverlapping patterns]
模式匹配是多余的
在一种情况下,可选择:false->。。。
|
15 |假->案例snd x。。。
|
17 |假->x:y:ys
| ^^^^^^^^^^^^^^^
好的,加载了一个模块。
因此,我不确定它是否能按预期工作。尽管Mark Seemann的版本可以改进 首先,让我们制作
agregarMon
的m
和p
实际参数:
agregarMon :: Monomio -> Polinomio -> Polinomio
agregarMon m p = case m of
(0,0) -> p
x -> case p of
[] -> [x]
y:ys -> case (snd x == snd y) of
true -> case ((fst x + fst y)==0) of
true -> ys
false -> (fst x + fst y , snd x):ys
false -> case snd x < snd y of
true -> y: agregarMon x ys
false -> x:y:ys
现在我们有一些简单的例子和一个复杂的例子,但即使是复杂的例子也不难阅读和理解(我甚至假设你在研究多项式、系数和幂)
您可以在那里运行它:
也许此链接将帮助您更好地理解在代码中进行分支的不同方法:
错误:true
这里只是一个变量名,与构造函数true
无关(大写T
!)。因此,上面的代码片段相当于
case (snd x == snd y) of { x ->
因此,模式匹配任何布尔值,True
和False
。因此,将永远不会考虑另一个分支false->…
我建议您启用警告,因为这样做会使GHC将第二个分支报告为冗余代码。编译器认为一个分支是无用的这一事实表明代码中存在严重错误
最后,根据我的经验,代码如下
case something of
True -> a
False -> b
这并不常见,因为我们可以把它写成
if something
then a
else b
在我看来,这更容易阅读。老实说,基于布局的格式与手动大括号/分号的奇怪组合让我很难说出编译器认为您的代码是什么意思。如果你把所有的
{}都去掉,就更容易理解了代码>字符,并正常布局。警告:true
不是true
,它是一个变量名,与任何其他名称一样,它将与任何布尔值匹配,包括False
!启用警告以帮助GHC发现此类错误。每个人都在抱怨格式,但@chi已经注意到了真正的问题。非常感谢!我不敢相信我在这么简单的事情上浪费了这么多时间,我会试着提出警告。我是这样写的,因为这就是我被教导去做的,我在互联网上看到每个人都像你一样写,这可能是有原因的,但我现在必须这样做。再次感谢@豺狼,即使如果更常见,使用案例。。真->;False->…
是一个很好的学习练习。布尔函数在Haskell中不像在其他语言中那么重要,初学者往往过度使用if
和部分函数,如果case
更好的话。因此,学习案例非常重要。
case (snd x == snd y) of { true ->
case (snd x == snd y) of { x ->
case something of
True -> a
False -> b
if something
then a
else b