haskell - 解决haskell数据记录中的循环依赖

标签 haskell record cyclic-dependency

想象一下,我想编写一个处理播客提要的应用程序。要存储来自此类提要的解析信息,我会编写如下内容:

data Podcast = Podcast {
    podcastTitle :: String, -- ^ title of podcast
    episodes :: [Episode]   -- ^ list of episodes of podcast
    ...                     -- ^ some other fields
} deriving (Show)

data Episode = Episode {
    episodeTitle :: String, -- ^ title of episode
    podcast :: Podcast      -- ^ podcast this episode belongs to
    ...                     -- ^ some other fields
} deriving (Show)

上述数据记录定义反射(reflect)了数据类型之间常见的 1:n 关系:一个播客有很多集,而集属于一个播客。现在我在定义此类播客时遇到问题:请定义 Podcast我已经需要剧集列表,但要定义 Episode我需要 Podcast 的实体实体。在我看来,在haskell中解决这种循环依赖是不可能的......

我也认为上面的代码是我用其他语言编程的遗留物。在上述风格中,我会以 python 为例,但是这种编程语言有一个状态的概念。在 python 中,我可以先定义一个 Podcast没有剧集的实体,然后使用定义的 Podcast 初始化所有剧集实体然后设置episodes播客字段添加到剧集列表。

我的问题:对播客和剧集之间的 1:n 关系建模的 Haskell 方法是什么?

评论中问题的答案:

为什么一集必须引用特定的播客?有一个功能会很好
podcast :: Episode -> Podcast

它会在我需要时返回剧集的播客。我知道,一种解决方案是也通过 Podcast情节的每个功能的实体,即我替换每个功能
func1 :: Episode -> Something

我需要上面的podcast功能与
func1 :: Podcast -> Episode -> Something

编写尽可能少的代码并且不需要携带 Podcast 会很棒。到处都是实体。

也许我稍微改变一下我的问题:定义 Episode 完全可以。没有 podcast 的数据记录 field 。如何实现
podcast :: Episode -> Podcast

在这种情况下?

如果有人稍后制作包含其他播客的剧集的播客怎么办?就我而言,这不会发生,即使是这样,将同一集视为不同的集是完全可以的。 (事实上​​,考虑到这个问题会将 1:n 关系提升为 n:n 关系,但如何在 haskell 中定义这些关系的主要问题仍然是相同的)。

最佳答案

在 Haskell 中,循环依赖实际上非常简单。在 let声明,任何绑定(bind)的定义都可以引用任何其他绑定(bind)。

let pc = Podcast "the name" [ep1, ep2]
    ep1 = Episode "first" pc
    ep2 = Episode "second" pc

懒惰会为你解决这个问题。

但作为一般规则,DBMS 是此类信息的最佳选择。

关于haskell - 解决haskell数据记录中的循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22696442/

相关文章:

android - 将短数组从音频记录转换为字节数组,而不降低音频质量?

f# - F# 中不同文件的类型和函数之间的循环依赖问题

haskell - 如何声明函数(可能是类型误解)

haskell - 在 Fay 中将 Char 转换为 ASCII 码

递归时Haskell Print?

Angular 8 : Cannot instantiate cyclic dependency - ActivatedRoute

c++ - 命名空间内类的循环依赖问题

haskell - 如何仅编译具有 '-auto' 成本中心的某些模块?

scala - 通用实体记录 scala - 引入无形状的 id 字段

vhdl 不能对记录进行切片