【问题标题】:Haskell: List of words paired with a number in a tupleHaskell:与元组中的数字配对的单词列表
【发布时间】:2025-12-17 08:10:01
【问题描述】:

我需要从第 4 阶段到第 5 阶段的帮助。我不确定是否有一个 Haskell 函数可以获取每个元素并将其放入一个元组中。也许我已经手动执行此操作,我也不知道该怎么做。

到目前为止,这是我的功能:

splitLines :: String -> [[String]]
splitLines splitLinesStr = splitWords (lines splitLinesStr)

splitWords :: [String] -> [[String]]
splitWords splitWordList = map words splitWordList

tupleNums tupleNumList = zip [1..] tupleNumList

第一阶段:例如原始输入,

"a&b b c.\na dd\n"

第 2 阶段:原始输入,拆分为行列表,如

["a&b b c.", "a dd"]

第 3 阶段:行列表,进一步拆分为单词列表,如

[["a", "b", "b", "c"], ["a", "dd"]]

第 4 阶段:列表列表,“元组”,以便将行号附加到它们,如

[(1,["a", "b", "b", "c"]), (2,["a", "dd"])]

第 5 阶段:单词列表(都在顶层),每个单词都与其行号配对,如

[(1,"a"), (1,"b"), (1,"b"), (1,"c"), (2,"a"), (2,"dd")]

【问题讨论】:

  • 也许您应该添加另一个阶段:将单个元组 (a, [b,c,d]) 添加到列表 [(a,b), (a,c), (a,d)]

标签: list function haskell tuples


【解决方案1】:

我们可以设计一个函数来获取第 4 阶段列表中的每个元素:

helper :: (Int, [a]) -> [(Int, a)]
helper (num, xs) = zip (repeat num) xs

然后我们就可以使用concatMap :: (a -> [b]) -> [a] -> [b]:

fourToFive :: [(Int, [a])] -> [(Int, a)]
fourToFive = concatMap helper

仅此而已。这是一个例子:

λ> fourToFive [(1, ["This", "is", "a", "line."]), (2,["This","is","another."])]
[(1,"This"),(1,"is"),(1,"a"),(1,"line."),(2,"This"),(2,"is"),(2,"another.")]

【讨论】:

  • 只是一个旁注,helper = uncurry (zip . repeat)
【解决方案2】:

您所要做的就是应用mapconcat 的组合。演示在ghci:

λ> let x = [(1,["a", "b", "b", "c"]), (2,["a", "dd"])]
λ> map (\(y,z) -> map (\a -> (y,a)) z) x
[[(1,"a"),(1,"b\"),(1,"b"),(1,"c")],[(2,"a"),(2,"dd")]]

请注意,我使用了两个 map 函数。外部map 将遍历x 的元素。 x(它是一个元组)的每个元素都与(y,z) 进行模式匹配。我们知道z 是一个列表。因此,我们使用另一个map 来遍历列表z。这个内部map 函数将返回一个(y,a) 的元组,其中a 是列表z 中正在遍历的当前元素,y 是该元组的第一个元素。

现在您需要做的就是在结果列表上应用concat 函数:

λ> concat $ map (\(y,z) -> map (\a -> (y,a)) z) x
[(1,"a"),(1,"b"),(1,"b"),(1,"c"),(2,"a"),(2,"dd")]

【讨论】: