将列表添加到 Haskell 中的列表列表
Add a list to a list of lists in Haskell
如何将列表添加到列表列表中?假设我想将 itemz
添加到 bagList
,这是一个列表列表。我该怎么做?
bagList itemz = mappend bagList itemz
你可以考虑加在最前面,这样更快:
bagItem bag item = item : bag
而且看起来你是来自命令式思维,你在 =
前后使用 bagList
的方式不太正确:[=14 前后的表达式=] 并不真正代表相同的结构。在 =
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.
中寻找关于差异列表的部分
更新
从评论来看,您真正要找的似乎是 Map
s。我们可以做一个 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)]
如何将列表添加到列表列表中?假设我想将 itemz
添加到 bagList
,这是一个列表列表。我该怎么做?
bagList itemz = mappend bagList itemz
你可以考虑加在最前面,这样更快:
bagItem bag item = item : bag
而且看起来你是来自命令式思维,你在 =
前后使用 bagList
的方式不太正确:[=14 前后的表达式=] 并不真正代表相同的结构。在 =
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.
中寻找关于差异列表的部分更新
从评论来看,您真正要找的似乎是 Map
s。我们可以做一个 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)]