我正在尝试构建一个元组列表。输入是元组[([char], int1, int2), ...]
的列表,输出是元组列表,[([char], int1, int2, (int1/int2)), ...]
。我知道下面的代码是错误的,因为我认为它正在构建一个元组列表[[(),(),(),()], [(),(),(),()]]
。
代码:
{- 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按降序排列?
答案 0 :(得分: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
那里。
答案 1 :(得分:1)
此代码无法编译(语法错误),但在修复后(我建议阅读syntax of list comprehensions(','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]
我会把排序留给你。
答案 2 :(得分: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 函数只返回一个表单元组(标题,值,权重,值/权重)。 地图是一个内置函数,它只是将给定函数应用于列表的每个元素。
sortFracListByValueWeightRatio (对于长名称而言)使用内置的 sortBy 函数(来自Data.List),该函数使用自定义函数对给定列表进行排序比较项目。 Sorter 是我的商品比较器,它只是比较价值/重量比率并返回GT或LT(大于/小于)。因此,使用自定义比较器比较列表项,并根据其答案进行排序。
可读性的显着提高可能是使用类型来描述值而不仅仅是元组。我也在测试列表中使用双打,但这很容易改变。