Haskell,不同类型列表的列表,检索值(frac背包概率)

时间:2012-07-30 17:07:10

标签: haskell knapsack-problem

到目前为止,我正试图在haskell中做分数背包问题

代码:

{- Input "how much can the knapsack hole <- x" "Possible items in sack [(label, value, weight), ...]" -}
knap x [] = []
knap x y = if length y == 1 then 

输入列表的格式为[([Char],Integer,Integer),...]列表(列表,字符,整数和整数)。

我的问题是试图拉出可能放在背包中的每件物品的标签,价值和重量。 (从列表中拉出值)

在我的前奏&gt;提示我正在做一些尝试

ghci输出:

Prelude> let x = [("label 1", 2, 14), ("label 2", 1, 15)]
Prelude> :t x
x :: [([Char], Integer, Integer)]
Prelude> length x
2
Prelude> x !! 0
("label 1",2,14)
Prelude> x !! 0 !! 1

<interactive>:1:1:
    Couldn't match expected type `[a0]'
                with actual type `([Char], Integer, Integer)'
    Expected type: [[a0]]
      Actual type: [([Char], Integer, Integer)]
    In the first argument of `(!!)', namely `x'
    In the first argument of `(!!)', namely `x !! 0'

如你所见,我正在努力做清单!!索引!!索引尝试从“项目”中减轻重量。这样做的正确语法是什么?

2 个答案:

答案 0 :(得分:2)

(a,b,c)是一个元组,而不是列表。您不能在元组上使用!!。毕竟:!!的类型对于元组会是什么样的?

从元组中获取值的方法是使用这样的模式匹配:

let (name, x, y) = theTuple in
-- ...

模式匹配通常也是获取列表头部的首选方式。因此,处理元组列表的函数通常看起来像这样:

f [] = -- handle the empty list
f ((name, x, y) : rest) =
  -- do something with name, x and y and then recurse on rest

答案 1 :(得分:2)

嗯,!!运算符仅适用于列表,正如您可以从其类型签名中看到的那样:[a] -> Int -> a

如果您想坚持使用元组,可以使用fstsnd的样式为3元组定义自己的函数。你可以用模式匹配来做到这一点;类似的东西:

first :: (a,b,c) -> a
first (a,_,_) = a

但是,为项目设计数据类型可能更好,并使用记录来提取所需的字段。

data Item = Item { label  :: String
                   value  :: Int
                   weight :: Int
                 }

然后,要制作新项x,您可以使用let x = Item {label = "label 1", value = 2, weight = 14}

现在您可以将背包建模为[Item]类型的项目列表,并获取第一项的值,您可以使用value $ knapsack !! 0,其中knapsack是您的列表物品。