Haskell:单词列表与元组中的数字配对

Haskell: List of words paired with a number in a tuple

我需要帮助才能从第 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 阶段:列表的列表,"tupled" 以便为它们附加行号,如

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

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

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

您所要做的就是组合应用 mapconcatghci 中的演示:

λ> 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 函数将 return 一个 (y,a) 的元组,其中 a 是在列表 zy 中遍历的当前元素是元组的第一个元素。

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

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

我们可以设计一个函数来获取第 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.")]