haskell - 如何在持久化中存储代数数据类型

标签 haskell yesod persistent

对于这样的数据类型

data Tree = Node String Tree Tree
          | Leaf String

像这样的真实数据
my_tree = (Node "first node" (Leaf "leaf") (Node "second node" (Leaf "leaf") (Leaf "leaf")))

如何使用持久性将其存储到数据库中,特别是如何执行“OR”部分?

我试过这样定义模型
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
    Tree
        value String
        leftTree Leaf
        rightTree Leaf
        deriving Show
    Leaf
        value String
        deriving Show
|]

递归结构将作为 json 字符串自动存储在一行中的列中,这非常好。但是我们如何或可以在持久模型中定义“OR”结构?

最佳答案

Persistent 只能存储没有子数据的 ADT。 IE。可以存储以下内容:

data Tag = Leaf | Fork

但是如果不将其序列化为 JSON,就无法存储像这样的递归结构:
data Tree a = (Leaf a) | Fork (Tree a) (Tree a)

您必须了解的是 Persistent 是数据库顶部的类型保存层,因此您必须根据在数据库中存储的效率来考虑您的模式,而不是根据方便的 Haskell 数据结构来考虑。
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
    Tree
        parent TreeId Maybe
        value String
        deriving Show
|]

此模式将为您提供以下结构的等效项。
data Tree a = Value a [Tree a]

关于haskell - 如何在持久化中存储代数数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22057994/

相关文章:

haskell - 使用按键列表进行选择 持久 (Yesod)

haskell - 顶层的裸露表达用于简单的 Template Haskell 实验

haskell - 具有 RankNTypes 的新类型

performance - 为什么基于 Haskell 枚举器的 IO 如此频繁地调用 sigprocmask?

haskell - 计算 Haskell 中排序列表中最常出现的数字

haskell - 如何在reactive-banana中实现游戏循环?

haskell - Yesod 和堆栈中缺少 cabal 依赖项

authentication - yesod - 密码保护登台站点

rest - 如何在 Haskell 中实现 HATEOAS?

Ruby:Net::HTTP 空闲超时?