简体   繁体   English

无法将预期类型“(t1,t2,t0)”与实际类型“ [a0]”匹配

[英]Couldn't match expected type `(t1, t2, t0)' with actual type `[a0]`

I'm trying to solve a fractional knapsack problem with the input, 我正在尝试用输入法解决小背包问题,

[("label 1", value, weight), ("label 2", value, weight), ...]

and the output, 和输出,

[("label 1", value, solution_weight), ("label 2", value, solution_weight), ...]

but I keep getting the error in computeKnapsack : 但是我不断在computeKnapsack得到错误:

"Couldn't match expected type `(t1, t2, t0)' with actual type `[a0]`"

I can't understand what the problem might be. 我不明白可能是什么问题。 I'm trying to create a list of 3-entry tuples. 我正在尝试创建3项元组的列表。 How can I get it to stop expecting a single 3-entry tuple? 我如何才能停止期望一个3项元组呢?

fst3 (a,b,c) = a
snd3 (a,b,c) = b
trd3 (a,b,c) = c
fst4 (a,b,c,d) = a
snd4 (a,b,c,d) = b
trd4 (a,b,c,d) = c
qud4 (a,b,c,d) = d

sortFrac (a1, b1, c1, d1) (a2, b2, c2, d2)
  | d1 > d2 = GT
  | d1 <= d2 = LT

fracKnap (x:xs) =
    fractionalKnapsack (x:xs) []

fractionalKnapsack (x:xs) fracList =
    if length (x:xs) <= 1
        then computeKnapsack (sortBy sortFrac (((fst3 x),(snd3 x),(trd3 x),(snd3 x) / (trd3 x)):fracList)) 100
        else fractionalKnapsack xs (((fst3 x),(snd3 x),(trd3 x),(snd3 x) / (trd3 x)):fracList)

computeKnapsack (x:xs) weightLeft =
    if length (x:xs) <= 1
        then (fst4 x, snd4 x, ((floor (weightLeft / (qud4 x)))*(qud4 x)))
        else (fst4 x, snd4 x, ((floor (weightLeft / (qud4 x)))*(qud4 x))):(computeKnapsack xs (weightLeft-(floor (weightLeft / (qud4 x))*(qud4 x))))

In the then branch of computeKnapsack the result is a single 3-tuple, but in the else branch it is a list of 3-tuples. computeKnapsackthen分支中,结果是单个3元组,但是在else分支中,结果是3元组列表。


I'm going to rewrite computeKnapsack for you. 我将为您重写computeKnapsack I'll start with your version with the error fixed: 我将从您的版本开始,并修复错误:

computeKnapsack (x:xs) weightLeft =
    if length (x:xs) <= 1
        then [(fst4 x, snd4 x, ((floor (weightLeft / (qud4 x)))*(qud4 x)))]
        else  (fst4 x, snd4 x, ((floor (weightLeft / (qud4 x)))*(qud4 x))) : (computeKnapsack xs (weightLeft-(floor (weightLeft / (qud4 x))*(qud4 x))))

First, I'm going to say what happens if the first argument to computeKnapsack is the empty list: 首先,我要说一下,如果computeKnapsack的第一个参数是空列表,将会发生什么:

computeKnapsack []     _          = []
computeKnapsack (x:xs) weightLeft =
    (fst4 x, snd4 x, ((floor (weightLeft / (qud4 x)))*(qud4 x))) : (computeKnapsack xs (weightLeft-(floor (weightLeft / (qud4 x))*(qud4 x))))

It enables us to get rid of the if -test, making the code shorter overall and easier to understand. 它使我们摆脱了if -test,使代码总体上更短并且更易于理解。

Next, I'll deconstruct x : 接下来,我将解构x

computeKnapsack []             _          = []
computeKnapsack ((a,b,_,d):xs) weightLeft =
    (a, b, ((floor (weightLeft / d))*d)) : (computeKnapsack xs (weightLeft-(floor (weightLeft / d)*d)))

You might prefer to follow leftaroundabout's suggestion to create a record type with meaningful names instead. 您可能更喜欢遵循leftaboutabout的建议来创建具有有意义名称的记录类型。 But if you do continue to use a tuple, deconstructing it by pattern matching is much clearer than using your fst4 , snd4 etc functions. 但是,如果您确实继续使用元组,则通过模式匹配对其进行解构比使用fst4snd4等函数要清晰得多。

Again, the code is now shorter and easier to understand, though it might help if we used more meaningful names than a , b , and d . 同样,现在的代码更短了,更容易理解,尽管如果我们使用比abd更有意义的名称可能会有所帮助。

We can continue in this vein: 我们可以继续这样:

computeKnapsack []             _          = []
computeKnapsack ((a,b,_,d):xs) weightLeft = (a, b, weight) : (computeKnapsack xs (weightLeft - weight))
  where weight = floor (weightLeft / d) * d

Here I've spotted that the same value was being calculated in two different places, and extracted that value into its own named variable. 在这里,我发现正在两个不同的位置计算相同的值,并将该值提取到其自己的命名变量中。 weight only needs to be calculated once instead of twice, so computeKnapsack is now marginally more efficient. weight只需要计算一次,而无需计算两次,因此现在, computeKnapsack效率computeKnapsack More importantly, I now understand what computeKnapsack is doing. 更重要的是,我现在了解了computeKnapsack在做什么。

I understand that you're new to Haskell. 我了解您是Haskell的新手。 Please take this as constructive suggestions on how you can write clearer Haskell code. 请将此作为关于如何编写更清晰的Haskell代码的建设性建议。

I've taken the liberty of cleaning up your computeKnapsack function so you can more clearly see the problem: 我已经清理了您的computeKnapsack函数,这样您就可以更清楚地看到问题所在:

computeKnapsack (x:xs) weightLeft =
 let e = (fst4 x, snd4 x, floor (weightLeft / qud4 x) * qud4 x)
  in if length (x:xs) <= 1
     then e
     else e:computeKnapsack xs (weightLeft - floor (weightLeft / qud4 x) * qud4 x)

My changes were purely cosmetic. 我的改变纯粹是表面上的。 Even after my changes your computeKnapsack function is still broken, a bad algorithm, and bad coding style. 即使在更改之后,您的computeKnapsack函数仍然损坏,算法错误且编码风格错误。

You can see from the rewritten version that your if statement has two branches, one returns a tuple, and the other returns a list of tuples. 从重写的版本中可以看到, if语句具有两个分支,一个分支返回一个元组,另一个分支返回一个元组列表。 You can fix it simply by changing the first branch to return a list with a single element: 您可以简单地通过更改第一个分支以返回包含单个元素的列表来解决此问题:

computeKnapsack (x:xs) weightLeft =
 let e = (fst4 x, snd4 x, floor (weightLeft / qud4 x) * qud4 x)
  in if length (x:xs) <= 1
     then [e]
     else e:computeKnapsack xs (weightLeft - floor (weightLeft / qud4 x) * qud4 x)

Also, before you submit a third question to StackOverflow, please take the time to complete an introductory tutorial to Haskell like http://learnyouahaskell.com/ which will help fix a lot of your problems. 另外,在向StackOverflow提交第三个问题之前,请花些时间完成Haskell入门教程,例如http://learnyouahaskell.com/ ,这将有助于解决许多问题。

One problem that throws that error in in the then of fractionalKnapsack . 一个问题在fractionalKnapsack背包中抛出该错误。 In that line you call function computeKnapsack with a tuple as the input instead of a list . 在该行中,您以元组(而不是list作为输入调用函数computeKnapsack

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法将预期类型(Int - &gt; Int - &gt; Int)与实际类型`(t0,t1,t2)&#39;匹配 - couldn't match expected type (Int -> Int -> Int) with actual type `(t0, t1, t2)' 无法匹配预期类型`[([Char],a0)]&#39;与实际类型`([Char],t0)&#39;Haskell - Couldn't match expected type `[([Char], a0)]' with actual type `([Char], t0)' Haskell 无法将预期类型 `(a1 -&gt; a1 -&gt; a1) -&gt; (t0 a0 -&gt; Int) -&gt; t Int -&gt; Int&#39; 与实际类型 `Int&#39; 匹配 - Couldn't match expected type `(a1 -> a1 -> a1) -> (t0 a0 -> Int) -> t Int -> Int' with actual type `Int' 无法将预期类型[a0]与实际类型IO()匹配 - couldn't match expected type [a0] with actual type IO () Haskell 预期类型:[t0 a0] 实际类型:[a] - Haskell Expected type: [t0 a0] Actual type: [a] Haskell“无法将预期类型“ a”与实际类型“ [a0]”匹配” - Haskell “Couldn't match expected type ‘a’ with actual type ‘[a0]’” 无法将预期的类型“ IO()”与实际类型“ a0-&gt; m0 a0”匹配 - Couldn't match expected type `IO ()' with actual type `a0 -> m0 a0' Haskell:无法将期望的类型“ IO t0”与实际类型“ Integer”匹配 - Haskell: Couldn't match expected type 'IO t0' with actual type 'Integer' 无法将预期类型`Maybe(String,Int,String)&#39;与实际类型`([Char],t0,[Char])&#39;匹配 - Couldn't match expected type `Maybe (String, Int, String)' with actual type `([Char], t0, [Char])' 无法将预期类型&#39;(Int,Int)&#39;与实际类型&#39;[t0]&#39;相匹配 - Couldn't match expected type ‘(Int, Int)’ with actual type ‘[t0]’
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM