Parsing 如何在haskell中更新关联映射时处理内容

Parsing 如何在haskell中更新关联映射时处理内容,parsing,haskell,state,Parsing,Haskell,State,如何在Haskell中实现一个在命令式语言中非常简单的转换,因为它可以轻松地更新映射及其内容 while( line = next()) { Data d = parse(line); if( map.get(d.key) == null) map.put(d.info); else map.get(d.key).update(d.info); } for(d : map.values) print d.computeResult() 为了给出(过于简化的)具体示例,输入将包含需

如何在Haskell中实现一个在命令式语言中非常简单的转换,因为它可以轻松地更新映射及其内容

while( line = next()) {
  Data d = parse(line);
  if( map.get(d.key) == null) map.put(d.info);
  else map.get(d.key).update(d.info);
}

for(d : map.values) print d.computeResult()
为了给出(过于简化的)具体示例,输入将包含需要通过某种规则关联的行。在这里,程序应该检测到键“k”下的值正在被添加、更新但最终被删除,并且不应该出现在输出中

[time] ADD key=k, value1=V1
[time] ADD key=k, value2=V2
[time] ADD key=k, value1=ABC
[time] [...]
[time] DEL key=k
[time] ADD key=k2, value1=V1

我是否应该考虑使用透镜,状态单元格,用键对数据进行分类(如果可能的话)还是别的什么?哪种方法是实现这一点最干净的方法(最少的样板文件)?我想知道这样的Haskell脚本是否比awk/sed/grep/xmlstartet-soup更容易维护。

insert::Ord k=>k->a->Map ka->Map ka
from
Data.Map
正是您想要的

import qualified Data.Map as M

addLines :: [String] -> M.Map Int String
addLines = foldr (uncurry M.insert) M.empty . parseLines
    where parseLines :: [String] -> [(Int, String)]
          parseLines = zip [1..]
addLines
获取要存储的行列表,并返回一个
Map
,其中行号作为行的键。如果您只是将一堆文本拼凑成一个
字符串
,请使用
行::字符串->[String]
将其拆分成行

正如Gabriel在评论中所建议的,将行列表转换为
地图的更好方法是

addLines = M.fromList . zip [1..]

注意:第一个函数允许您传入一个初始的
Map
,而不是
M.empty
,但是使用
M.union
Map
s与第二个函数组合起来可能会更快。

插入::Ord k=>k->a->Map k->a->Map k->a
来自
数据。Map Map
正是您想要的

import qualified Data.Map as M

addLines :: [String] -> M.Map Int String
addLines = foldr (uncurry M.insert) M.empty . parseLines
    where parseLines :: [String] -> [(Int, String)]
          parseLines = zip [1..]
addLines
获取要存储的行列表,并返回一个
Map
,其中行号作为行的键。如果您只是将一堆文本拼凑成一个
字符串
,请使用
行::字符串->[String]
将其拆分成行

正如Gabriel在评论中所建议的,将行列表转换为
地图的更好方法是

addLines = M.fromList . zip [1..]

注意:第一个函数允许您传入一个初始的
Map
,而不是
M.empty
,但是使用
M.union
Map
s与第二个函数组合可能会更快。

更好的是,使用
Data.Map.fromList
(也应该更快)。。。。如果您还想添加另一个映射,请使用
Data.map.union
。更好的是,使用
Data.map.fromList
(也应该更快)。。。。如果您还想添加另一个映射,请使用
Data.map.union