[因此,我试图创建此功能AgregarMon,该功能基本上是将“ Monomio”添加到“ Polinomio”Monomio最终将成为Polinomio内部的一个列表元素。您将稍微了解一点]
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;}}}}
我一直在看我的代码,就像一个小时,但我找不到问题。错误说:
Polinomios.hs:45:140: error:
Unexpected case expression in function application:
case ((fst x + fst y) == 0) of
true -> ys
false -> (fst x + fst y, snd x) : ys
You could write it with parentheses
Or perhaps you meant to enable BlockArguments?
|
45 | y:ys -> case (snd x == snd y) of { true -> case ((fst x + fst y)==0) of { true -> ys; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
第45行是代码上方的第四行。对不起,如果我缺少信息,请现在让我。以防万一,有人不知道,fst和snd在前奏中。 fst从“ Monomio”中获取第一个元素,然后从第二个元素获取。 fst =(a,b)-> a snd(a,b)-> b
虽然您可以在紧急情况下使用大括号和分号,但Haskell并不是基于C的语言。 idiomatically uses indentation表示功能范围。
类似的东西会更惯用:
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
这会编译(尽管有警告,请参阅下文),但是我不知道它是否可以完成您想要的工作。 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.
因此,我不确定它是否按预期工作。
首先,让m
和p
成为agregarMon
的实际参数:
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 (0, 0) p = p agregarMon x [] = [x] agregarMon (f, s) (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
条件检查的结果与case
进行模式匹配并不是那么习惯,最好使用if
或警卫:
agregarMon :: Monomio -> Polinomio -> Polinomio agregarMon (0, 0) p = p agregarMon x [] = [x] agregarMon x@(coefx, powx) (y@(coefy, powy):ys) | powx == powy = if coefx + coefy == 0 then ys else (coefx + coefy, powx):ys | powx < powy = y:agregarMon x ys | otherwise = x:y:ys
现在我们有一些简单的情况和一个复杂的情况,但是即使是复杂的情况也不是很难阅读和理解的(我什至假设您正在使用多项式,系数和幂)。您可以在此处运行它:https://repl.it/@Yuri12358/so-monomio-polinomio
也许此链接将帮助您提高对代码分支的不同方法的理解:http://learnyouahaskell.com/syntax-in-functions#pattern-matching
case (snd x == snd y) of { true ->
是错误的:true
这里只是一个变量名,与构造函数True
不相关(大写字母T
!)。因此,以上代码段等同于
case (snd x == snd y) of { x ->
因此,模式匹配任何布尔值True
和False
。因此,将不再考虑其他分支false -> ...
。我建议您打开警告,因为这样做会使GHC将第二个分支报告为冗余代码。编译器认为分支无用这一事实表明,代码存在某些问题。