我是Haskell的新手,我想知道合并任意数量项目的任意数量的列表的最有效方法。这是示例数据:
LIST 1: steve
2014-01-20 | cookies | steve
LIST 2: chris
2014-02-05 | cookies | chris
LIST 3: mark
2014-09-30 | brownies | mark
2014-03-30 | candy | mark
2014-05-12 | pie | mark
LIST 4: anthony
2014-05-18 | cookies | anthony
2013-12-25 | fudge | anthony
LIST 5: andy
2014-10-04 | cookies | andy
LIST 7: john
2014-06-19 | pie | john
RESULTING LIST
2014-10-04 | cookies | andy chris steve anthony
2014-09-30 | brownies | mark
2014-06-19 | pie | john mark
2014-03-30 | candy | mark
2013-12-25 | fudge | anthony
请注意,这些列表都是以人为本,可能会或可能不会按日期排序,结果需要合并先前的列表,分组并创建一个列表,其中甜点是唯一的,但有一个组成人员列表吃了它,按时间顺序按时间顺序排序。
答案 0 :(得分:1)
解决问题的最佳方式是什么,在大多数情况下,无论是在haskell还是在我认为的任何其他编程语言中都无法回答。
更好的方法是考虑,如何解决这个问题(根本),并在脑海中保留一些原则。
也许我已经忘记了一些事情,但是对于你的问题,我想给出一个提示列表
如果我提前知道所有项目和名称,我会使用代数数据类型来模拟这种情况
data Name = Mark | Chris ...
deriving (Ord,Eq,Show)
data Items = Pie | Cookies ...
deriving (Ord,Eq,Show)
如果我还不知道haskell如何表示日期数据类型,我可以使用普通的String
对此进行建模,或者我会使用hoogle查看是否已存在日期内容。
> hoogle date
...
Data.Time.Calendar...
...
所以我认为Data.Time.Calendar
模块似乎是一个不错的选择,我会查看其文档,可以找到online或者如果你在本地安装软件包,你可以使用haddock来生成它来自源文件。
接下来我要做的是模拟“数据库”,当然存在库以使用sqly stuff或acid-state数据库使用代数数据类型而不是数据库后端。但是为了更好地掌握haskell,我会尝试重新发明轮子一次并使用一个tupel列表,或者一个类似于字典的集合,它位于haskell中,名为Map
。但是使用Map
之一必须要小心并进行限定导入,因为大多数提供的函数都会导致名称与标准库中的函数冲突(Prelude)。
import qualified Map as M
并建模我的数据库我会使用Items作为键和日期元组和名称列表作为值,因为我想知道这是我的数据库我会为它提供类型别名。
type DB = M.Map Item (Date, [Name])
为了解决这个问题,我将再次浏览Map
文档,并很高兴找到函数insertWith
,empty
和toList
。对于insertWith
函数,我会想到max
和list cons (:)
函数的混合来创建新条目。
为了更好地感受整个事情,我会启动ghci
和import qualified Data.Map as M
,并使用M.Map String (String,[Int])
或其他一些例子来愚弄我们的数据,并在第一次近似中建模。
对于结果我必须按日期排序我的地图的toList
,这只是一个小问题。我toList myDb
的类型为[(Item,(Date,[Name]))]
,因此fst.snd
与sortBy
排序可能会产生预期结果。
在我做了这么多之后,我会休息并阅读一些关于解析器的内容 - 将我的所有文件都放在我的程序的上下文中。搜索引擎对你最不信任的搜索将会出现一些值得阅读的文章(Parser Parsec Haskell)。
如果所有这些都太复杂了,我会回去并将我的所有类型更改为Strings
,并希望在我有时间再次阅读解析器之前我不会有任何类型; - )。
对于中间步骤中的任何问题,此处的人员将很乐意为您提供帮助,假设您提供具体的问题/问题描述。
如果所有这些都不够高效,那么haskell提供的分析工具足以帮助我,但这是我最后一个需要解决的问题。