代码之家  ›  专栏  ›  技术社区  ›  Stephan Kulla

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

  •  4
  • Stephan Kulla  · 技术社区  · 11 年前

    想象一下,我想编写一个处理播客提要的应用程序。为了存储从这样的提要中解析的信息,我将编写如下内容:

    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 实体我需要 播客 实体在我看来,解决这种循环依赖性在haskell中是不可能的。。。

    我还认为以上代码是我用其他语言编程的残余。在上面的样式中,我会用python来实现,但这种编程语言有状态的概念。在python中,我可以首先定义 播客 实体,然后使用定义的 播客 实体,然后设置 episodes 将播客的字段添加到剧集列表中。

    我的问题: 用什么样的haskell方法来模拟播客和剧集之间的1:n关系?

    评论中问题的答案:

    为什么一集必须引用特定的播客? 能有个功能就好了

    podcast :: Episode -> Podcast
    

    它会在我需要的时候返回该集的播客。我知道,一个解决方案是通过 播客 事件的每个函数的实体,即我替换每个函数

    func1 :: Episode -> Something
    

    我需要上面的 podcast 具有的函数

    func1 :: Podcast -> Episode -> Something
    

    尽可能少地编写代码,而不必携带 播客 到处都是实体。

    也许我稍微改变一下我的问题: 插曲 没有 播客 领域如何实施

    播客::插曲->播客
    

    在这种情况下?

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

    1 回复  |  直到 11 年前
        1
  •  4
  •   Dan    11 年前

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

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

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

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