元组评估

时间:2016-11-12 22:44:04

标签: haskell

我正在编写以下类型的函数:

match :: [(String,a)] -> Maybe (String, a, a)

我希望函数遍历元组列表,并确定是否存在第一个元素(字符串)相同的元组。如果是这样,我想返回一个包含该字符串的元组,以及每个匹配元组中的第二个元素。如果没有匹配的元组,则返回“Nothing”。如果有多个匹配,则返回它找到的第一个匹配。

例如:

match [("x", 3), ("y", 4), ("z", "5"), ("x", 6)] = ("x", 3, 6)
match [("x", 3), ("y", 4), ("z", "5")] = Nothing

我在想:

match (x:xs) = if (fst x) = (fst xs) return (fst x, snd x, snd xs)
--if no matches, return Nothing

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

如果有三个或四个带有“x”的元组怎么办?你不能拥有可变长度的元组。也许你想要返回一个列表:

match :: [(String, a)] -> Maybe (String, [a])

如果有几个元组相匹配怎么办?你想要所有这些,还是仅仅是第一个?如果你想要它们,那么你应该返回一个匹配列表。

match :: [(String, a)] -> [(String, [a])]

如果您这样想,那么您可以看到将所有“x”对分组在一起,“y”对等等,将是一个良好的开端。您可以使用

执行此操作
sortBy (comparing fst) xs

comparing接受一个函数和两个值,将函数应用于每个函数,并比较结果。 sortBy使用其第一个参数作为比较函数,因此sortBy (comparing fst)按照每个元组中的第一个元素对列表进行排序。

然后您可以使用groupBy一起收集元素。

编辑:

groupBy的类型为

groupBy :: (a -> a -> Bool) -> [a] -> [[a]]

因此,您需要编写函数equalFirst以将其作为参数提供。那么

groupBy equalFirst $ sortBy (comparing fst) xs

会给你

[[("x", 3), ("x", 6)], [("y", 4)], [("z", 5)]]

这是一个列表清单。每个子列表都包含具有相同字母的元组。

现在你可以编写一个函数,它接受其中一个子列表并将其转换为你想要的结果。然后使用map将其应用于列表列表。