0

我一生都无法弄清楚为什么这个 if 语句有问题(haskell noobie。)有人能帮我吗?

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

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

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

computeKnapsack (x:xs) = (x:xs)
4

3 回答 3

8

:是“缺点”运算符。它通过在左侧提供“ head ”元素和在右侧提供“tail”列表来构造一个列表

ghci> 1 : [2,3,4]
[1,2,3,4]

您可以使用:.

ghci> let (x:xs) = [1,2,3,4]
ghci> x
1
ghci> xs
[2,3,4]

您在代码中使用的方式(x:xs)暗示您尚未牢牢掌握列表的定义或模式匹配的定义。而不是使用

if length (x:xs) <= 1

简单的模式匹配更为常见。一个简单的例子:

howMany :: [a] -> String
howMany [] = "Zero"
howMany [x] = "One"
howMany (x:xs) = "Many"

Haskell 函数可以用这样的“方程式”序列定义,您可以在其中对您感兴趣的可能情况进行模式匹配。这给我们带来了您的代码的其他问题,它们是:

  • 的方程式fractionalKnapsack不匹配。一个有 1 个参数,另一个有 2 个。您可能打算命名第二个fractionalKnapsack'
  • 这两个fractionalKnapsack定义都不处理空列表的情况。我不确定这一点;如果您知道永远不会给它一个空列表,这可能是可以接受的。
  • 您的任何函数都没有类型签名。类型推断可以推断它们,但通常最好先编写类型签名,以表达您对函数的意图并指导您实现它。
  • 的第二个定义fractionalKnapsack没有意义。符号后只能有一个表达式=,但您提供了两个,用换行符分隔。这是无效的 Haskell 并解释了为什么在“if”上有一个解析错误:因为你使用的任何编译器/解释器都不期望另一个表达式的开头!
于 2012-08-05T14:56:12.627 回答
8

这段代码有一些问题。您对 fractionalKnapsack 有两个不同的定义,每个都采用不同数量的参数,这显然会给编译器带来一些麻烦。此外,if 语句上的解析错误是因为实际上不应该有一个 if 语句,您试图在其中放置一个 if 语句,您在到达 if 语句之前已经完成了函数的定义。

如果你能更好地解释你正在尝试做什么,或者你期望你编写的代码会发生什么,这可能会有所帮助。

于 2012-08-05T07:27:53.767 回答
3

computeKnapsack sort(fracList)

这可能也是一个错误。它应该是computeKnapsack (sort fracList)(或者,等效地,computeKnapsack $ sort fracList)。

当你做时computeKnapsack sort(fracList),它等于做computeKnapsack sort (fracList),相当于做computeKnapsack sort fracList,意思是:“给 computeKnapsack 两个参数:sortfracList”。

于 2012-08-05T14:12:59.867 回答