解决haskell数据记录中的循环依赖性 [英] Solve cyclic dependencies in haskell data records

查看:155
本文介绍了解决haskell数据记录中的循环依赖性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下,我想编写一个处理播客feed的应用程序.为了存储来自这种提要的解析信息,我将编写如下内容:

Imagine I want to write an application which deals with podcast feeds. To store the parsed information from such a feed, I would write something like this:

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)

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

The above data record definitions reflect a common 1:n relation between data types: A podcast has many episodes and the episode belongs to one podcast. Now I have problems defining such podcast: Do define a Podcast I already need the list of Episodes but to define an Episode entity I need the Podcast entity. It seems to me, that solving this cyclic dependency is impossible in haskell...

我还认为上面的代码是我用其他语言编写的程序的一部分.在上面的样式中,我将以python为例,但是这种编程语言具有状态概念.在python中,我可以先定义一个没有情节的Podcast实体,然后使用定义的Podcast实体初始化所有情节,然后将播客的episodes字段设置为情节列表.

I also think that the above code is a relict from my programming in other languages. In the above style I would do it for example in python, but this programming language has a notion of state. In python I can first define a Podcast entity without episodes, initialize then all episodes with the defined Podcast entity and set then the episodes field of the podcast to the list of episodes.

我的问题:在播客和剧集之间建立1:n关系的haskell方法是什么?

My question: What is the haskell way to model the 1:n relation between podcasts and episodes?

对评论中的问题的答案:

Answers to questions in the comments:

为什么一个情节必须引用特定的播客?拥有功能会很好

podcast :: Episode -> Podcast

会在需要时返回剧集的播客.我知道,一种解决方案是将Podcast实体也传递给每个剧集的功能,即我替换每个功能

which returns the episode's podcast whenever I need it. I know, that one solution would be to pass also the Podcast entity to each function for episodes, i.e. I replace each function

func1 :: Episode -> Something

我需要上面的podcast函数

func1 :: Podcast -> Episode -> Something

那就太好了,编写尽可能少的代码,而不必携带Podcast实体到处都是.

It would be just great, to write as little code as possible and not to have the necessity to carry the Podcast entity everywhere around.

也许我可以稍微改变一下我的问题:定义没有podcast字段的Episode数据记录是完全可以的.如何实现

Maybe I change my question a litte bit: It would be totally okay to define the Episode data record without the podcast field. How can implement

podcast :: Episode -> Podcast

在这种情况下?

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

What if someone makes a podcast later on that includes episodes from other podcasts? In my case this will not happen and even if it is the case, it would be totally okay to consider the same episode as different ones. (In fact considering this issue would lift the 1:n relationship to an n:n relationsship, but the main question how to define those relationships in haskell remains the same).

推荐答案

在Haskell中,循环依赖实际上非常容易.在let语句中,任何绑定的定义都可以引用任何其他绑定.

Cyclic dependencies are actually really easy in Haskell. In a let statement, any binding's definition can refer to any other binding.

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

懒惰会帮你解决这个问题.

Laziness will take care of this for you.

不过,作为一般规则,DBMS是此类信息的最佳选择.

As a general rule though, a DBMS is the best choice for this sort of information.

这篇关于解决haskell数据记录中的循环依赖性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆