sql - 程序结构——简单的命令行待办事项列表应用程序——Haskell 的方式是什么?

标签 sql database data-structures haskell functional-programming

背景:我正在使用 Haskell 开发我的第一个完整程序,这是一个简单的命令行应用程序。

我的问题是一个结构问题,有两个层次:(1) 最好的方法是什么?和 (2) Haskell 的(函数式)方法是什么?我这样说的原因是因为我怀疑可能有一种更快或更简单的方法可以忽略函数式编程的原则。我想以更优雅、更清晰的方式进行,因为它更像是一种学习练习。

请记住,我(显然)希望应用程序具有一定的持久性。现在表中的两个选项是将信息存储在平面文本文件中,或者交替地存储在 Sqlite 数据库中。

我想到的第一个结构是这样的,其中 ToDoList 类型对象只是一个 ToDo 项目列表:

import Data.List
import Data.Time

data ToDo = ToDo {
        todoId       :: Int,
        todoDue      :: ZonedTime,
        todoCreated  :: UTCTime,
        todoItem     :: String,
        todoPriority :: Priority,
        todoStatus   :: Status
        }
        deriving (Show, Read)

type ToDoList = [ToDo]

data Priority = Low | Medium | High
        deriving (Show, Read, Eq, Ord)

data Status = Complete | InProgress | Open
        deriving (Show, Read, Eq, Ord)

但后来我开始想知道如何最好地存储这种类型的对象。这是否意味着我将它们存储在一个平面文件中?有没有办法将像这样的高度指定类型的对象与数据库中的字段/列相关联?

当我考虑使用 Sqlite 数据库时,似乎所有的工作都将在数据库调用中完成,Haskell 类型与它的关系相对较小。这似乎很糟糕。

总而言之,问题是我如何才能最好地为我的简单待办事项列表应用程序的数据结构建模,以符合函数式编程的概念和我正在寻求实践的 Haskell 理念项目?

最佳答案

Show/Read 组合是序列化和反序列化应用程序内部状态的一种极其简单的方法,而且由于纯粹性,它基本上也总是有效。此外,您将获得编写切片和切 block 列表函数的良好实践,因为您将能够将列表视为已完全加载到内存中(也许如果您想使用一些更高效的数据结构,您可以研究优化不同查询的方法。)

例如,如果我想查找在某个日期之前到期的所有项目,我可以使用到期过滤器来编写:

dueBefore (ToDoList ts) d = ToDoList (filter (\t -> due t <= d) ts)

伪代码中的一些风格挑剔:

  • 由于所有访问器函数(id、die.created...)都被转储到模块范围的命名空间中,因此最好在它们前面加上记录名称的前缀/后缀,例如 todoId、todoDie。在这种特殊情况下,id 是一个真正的函数,因此您不应该隐藏它!

  • ToDoList 是具有一个值的单个构造函数数据类型;您可能实际上只想要一个新类型或类型同义词。 (练习:重写上面的代码片段以使用类型同义词。)

  • 您可能需要一个关于优先级和状态的 Ord 实例

关于sql - 程序结构——简单的命令行待办事项列表应用程序——Haskell 的方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4383512/

相关文章:

c - 将冲突键哈希到哈希表中的下一个

php - 直接的SQL查询工作和通过PHP的SQL查询不是吗?

mysql - 根据子查询获取 COUNT 值

MySQL - 错误的值

mysql - 如何避免在 postgreSQL 中对列名使用双引号?

php - 无法让 UPSERT 在具有自动增量列和 FK 的 MYSQL 上工作

algorithm - 查找相邻元素至少相差 k 的最长递增子序列

Java 连接到 MS Access 数据库

database - 数据库表中的键值是否应该进行哈希处理?

c++ - 如何编写自定义词典比较器 C++