0

我正在尝试建立一个元组列表。输入是元组列表,[([char], int1, int2), ...]输出是元组列表,如[([char], int1, int2, (int1/int2)), ...]. 我知道下面的这段代码是错误的,因为我认为它正在构建一个 tuples 列表的列表[[(),(),(),()], [(),(),(),()]]

代码:

{- take a list of labels, values, and weights and return list of labels and fractions -}
fraclist [] = []
fraclist x = [ (y,r,q,z) : y <- first (head x) | r <- scnd (head x) | q <- last (head x) | z <- r/q ] : fraclist tail x

{- helper func to get values from tuples -}
frst (a,b,c) = a
scnd (a,b,c) = b
last (a,b,c) = c

我怎样才能得到所描述的正确的输出形式?另外,我如何输出排序的元组列表,使得z按降序排列?

4

3 回答 3

1

我想你只想

fraclist xs = [(y,r,q, r `quot` q) | (y,r,q) <- xs]

(注意:我使用quot而不是(/)因为您将组件命名为int1, int2。)

不使用列表推导的变体是

fraclist = map (\(y,r,q) -> (y,r,q, r `quot` q))

您的代码无法编译,在这种情况下,最好发布错误消息,以便人们一眼就能看出可能的原因是什么。

你得到一个解析错误在第<-一个

fraclist x = [ (y,r,q,z) : y <- first (head x) | r <- scnd (head x) | q <- last (head x) | z <- r/q ] : fraclist tail x

因为第一个将生成的表达式与生成器表达式分开(y,r,q,z) : y <- first (head x)之前的表达式格式不正确。|我认为这只是一个错字,你也打算使用|而不是(:)那里。

然后你的列表理解中有几个分隔符,没有扩展名|是无效的。ParallelListComp但是,代码看起来不像是您在此处尝试的真正的并行列表推导,因为所有三个值都是从同一个列表中提取的。最后,最后一部分| z <- r/q再次不是格式正确的,因为r/q它不是一个可以在列表推导中从中提取元素的列表。你可能打算let z = r/q在那里。

于 2012-07-30T18:30:14.193 回答
1

此代码无法编译(语法错误),但在修复之后(我建议阅读列表理解的语法(','s vs. '|'s))并进行一些其他更改:

  • 使用了列表理解,它负责基本情况和列表上的映射——所以我能够消除fraclist [] = []head//业务tail:

  • 使用模式匹配从输入元组中提取值——这通常比使用函数分离值更容易阅读

  • 为文档目的添加了显式类型签名

这就是我认为你的意思:

fraclist :: (Integral t1) => [(t, t1, t1)] -> [(t, t1, t1, t1)]
fraclist xs = [(x, y, z, div y z) | (x, y, z) <- xs]

我将把排序留给你。

于 2012-07-30T18:30:23.113 回答
0

这是一个没有列表理解的简单解决方案:

import Data.List

-- (string, int1, int2) -> (string int1, int2, (int1/int2))
fraclist list = map generateTuple list
    where generateTuple (label, value, weight) = (label, value, weight, (value)/(weight)) 

sortFracListByValueWeightRatio list = sortBy sorter list
    where sorter (_,_,_,d) (_,_,_,h) = if d > h then GT else LT

testList = [("first",3.0,4.0), ("second",4.0,7.0)]

没什么特别的(我一周只用过haskell)。

fraclist通过将 generateTuple 函数映射到列表来工作。generateTuple函数只返回一个形式的元组(标题、值、权重、值/权重)。Map是一个内置函数,它简单地将给定函数应用于列表的每个元素。

sortFracListByValueWeightRatio (对不起,名字太长了)使用内置的sortBy函数(来自 Data.List),它使用自定义函数对给定列表进行排序以比较项目。Sorter是我的项目比较器,它只是比较价值/重量比并返回 GT 或 LT(大于/小于)。因此,列表项使用自定义比较器进行比较,并根据其答案进行排序。

可读性的显着改进可能是使用类型来描述值而不仅仅是元组。我也在测试列表中使用双打,但这很容易改变。

于 2012-07-30T18:44:56.853 回答