繁体   English   中英

架构中的Haskell类型与类型类

[英]Haskell Types vs. Typeclasses in architecture

假设我有一个应用程序,其核心数据是项目,文档集(“ DocSets”)和文档(“ Docs”)。 文件不限于任何特定的内容类型; 它们可以是电子表格,图像,HTML等,并且可以具有其他文档所没有的功能/行为。 同样,根据我需要的行为类型,我可能有多种DocSet。 也许此DocSet将文档显示在一个平面列表中,也许使一个状态与每个文档相关联,并且基于状态具有一些很酷的呈现技巧。

如果我不使用类型类,则代码可能如下所示:

data Project = Project {
  projName :: Text,
  projDocSets :: [DocSet]
}

data DocSet = DocSet {
  dsName :: Text,
  dsDocs :: [Doc]
}

data Doc = Doc {
  docTitle :: Text,
  docType :: Text,
  docContents :: ByteString
}

我看到的问题是,它允许存在多种类型的Docs(通过docType字段),但实际上使用了手动类型检查,这在我看来并不对劲。 我可能有PagedTextDoc,ContinuousTextDoc,SpreadsheetDoc,ImageDoc等的数据构造函数。对我来说,这似乎很差。

编辑:我的“模块化差”评论依赖于沟通不佳的知识。 每个文档都有一些常见的行为((反序列化),被分组为一个DocSet,一个标题,一个呈现,随着应用程序的发展而出现的其他行为)和一些独特的行为(内部表示为易于编辑的格式,保存了增量编辑,假设应用程序是网络应用程序,则部分呈现为HTML)。

即使不是这种情况,在我看来,如果我可以创建一个新模块,定义我的文档以及可以使用的功能,那么该应用程序将更加模块化,现在支持文档。 这样,我在这里定义了我的分页文档,在那儿定义了我的电子表格,而两者根本就不在乎。

也许我可以为文档使用类型类?

data DocSet = DocSet {
  dsName :: Text,
  dsDocs :: [Doc]
}

class Doc d where
  docTitle :: d -> Text
  docType :: d -> Text
  docContents :: d -> ByteString

dsDocs的声明现在不进行类型检查。 列出仅适用于一种特定的具体类型,而不适用于任何类型类的成员。 DocSet绝对需要能够存储/引用多种文档。

我尝试进行一些搜索,但是坦率地说,我的Google技能在这里完全失败了。 我是否在正确考虑数据结构? 将所有(Proj,DocSet,Doc)作为单个数据构造函数的方法是否真的是处理此问题的最佳方法,还是我缺少Haskell处理多态性的方式?

好吧,基于类的建议甚至行不通。 类不是类型。 如果Doc是课程,则您不能拥有[Doc]

通常的方法是确定您要建模的对象。

您是否需要一堆行为统一且可以轻松打包在一起的东西? 然后将该行为归类。 通常,这是通过创建一条记录来完成的,该记录为您想要的每种行为提供一个函数。

另一方面,您是否有一堆需要非常不同的处理方式的东西? 在这种情况下,将数据放入一堆类型中,然后让类型检查器(和穷举性检查器)引导您进行操作,以确保您始终在正确的地方处理正确的事情。

我不建议为此使用类。 类(大多数情况下)仅在以下情况下才有用:您可以编写在具有具体类型时有意义的类型多态代码,但无需知道什么是类型。 (这是有点夸张,但与事实相近,足以将其用作一阶近似启发式。)

假设我有一个应用程序,其核心数据是项目,文档集(“ DocSets”)和文档(“ Docs”)。 文件不限于任何特定的内容类型; 它们可以是电子表格,图像,HTML等,并且可以具有其他文档所没有的功能/行为。

听起来您似乎不知道类型可以具有多个构造函数(求和类型)。 代替您的Doc请执行以下操作:

data Doc = PagedTextDoc {docTitle :: Text, docContents :: ByteString}
         | SpreadsheetDoc {docTitle :: Text, docContents :: ByteString}
       ... etc

同样,根据我需要的行为类型,我可能有多种DocSet。 也许此DocSet将文档显示在一个平面列表中,也许使一个状态与每个文档相关联,并且基于状态具有一些很酷的呈现技巧。

data DocSet = ListDocset Text [Doc] | KoolDocset [(Status, Doc)] | ...etc

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM