【发布时间】:2015-10-04 10:45:43
【问题描述】:
如何将列表添加到列表列表中?假设我想将itemz 添加到bagList,这是一个列表列表。我该怎么做?
bagList itemz = mappend bagList itemz
【问题讨论】:
如何将列表添加到列表列表中?假设我想将itemz 添加到bagList,这是一个列表列表。我该怎么做?
bagList itemz = mappend bagList itemz
【问题讨论】:
您可能要考虑在前面添加它,这样会更快:
bagItem bag item = item : bag
此外,您似乎来自命令式思维方式,您在 = 之前和之后使用 bagList 的方式不太正确:= 之前和之后的表达式并不真正代表相同建造。在= bagItem 被用作函数之前,= 之后它被用作一些Monoid(如果itemz 是一个列表,那么它也需要是一个列表)。
如果你真的想追加项目(这会更慢,因为操作需要一直遍历列表以在末尾添加新项目,并且需要重新构建整个列表)你可以按照 Christoph 的建议去做,或者您可以采用如下的递归公式:
appendItem :: a -> [a] -> [a]
appendItem i (x:xs) = x : appendItem i xs
appendItem i [] = i : []
如果你既想追加又担心性能,你应该看看差异列表,例如在this chapter in Learn You a Haskell中查找差异列表部分。
更新
从 cmets 看来,您真正在寻找的是Maps。我们可以创建一个Map,其中每个项目作为键,出现次数作为值。在您的情况下,这似乎是Map String Int。
import Data.List (foldl')
import qualified Data.Map as M
bag :: M.Map String Int
bag = M.empty
addToBag :: M.Map String Int -> [String] -> M.Map String Int
addToBag = foldl' go
where go m i = M.insertWith (+) i 1 m
main = print $ addToBag bag ["a","b","c","a"]
-- fromList [("a",2), ("b", 1), ("c", 1)]
【讨论】:
map length bag。如果您确实想在每组项目中存储数字,我可能会选择bag :: [(Int, [a])],其中项目列表及其长度一起存储在包中。然后,您可以像这样添加项目:bagItems bag items = (length items, items) : bag.