Haskell 如何在持久存储中存储代数数据类型

Haskell 如何在持久存储中存储代数数据类型,haskell,yesod,persistent,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"))) 如何使用persistent将其存储到数据库中,特别是如何执行“OR”部分 我尝试过这样定义模型 share [mkPersist sqlSettings,

对于这样的数据类型

data Tree = Node String Tree Tree
          | Leaf String
和真实数据一样

my_tree = (Node "first node" (Leaf "leaf") (Node "second node" (Leaf "leaf") (Leaf "leaf")))
如何使用persistent将其存储到数据库中,特别是如何执行“OR”部分

我尝试过这样定义模型

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
    Tree
        value String
        leftTree Leaf
        rightTree Leaf
        deriving Show
    Leaf
        value String
        deriving Show
|]

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

持久化只能存储没有子数据的ADT。即,可以存储以下内容:

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]
此模式将为您提供以下结构的等价物

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
    Tree
        parent TreeId Maybe
        value String
        deriving Show
|]
data Tree a = Value a [Tree a]

如果您的问题需要存储如此复杂的数据,那么使用acid状态可能更方便?同上。我正在试验从酸性状态迁移到碱性状态以节省内存。作为SQL的新手,我对实际进入数据库的类型的简朴感到惊讶。我必须将所有列表类型的记录字段“由内而外”。你是说“没有递归子数据”吗?这样就可以存储例如
data Tag=Leaf Int | Fork String
?@AlexeyRomanov,你知道,我从未尝试过。我打赌它实际上是可以存储的,尽管它需要先以某种方式序列化,而且我已经有一段时间没有看到持久代码的这一部分了。是的……我知道最后它只是数据库上的一层。我只是想知道,既然它足够聪明,可以将其更改为json,那么它是否也可以帮助将数据类型的结构保持为“或”???如果是,如何在模型中定义它?或者像你写的那样,树是一个可能,而叶子将永远在那里?还有,
parent TreeId maybe
如何转换为一个可能树列表?@HCC这是一个反向关系,意味着许多树行可以引用父树行。因此,当把它写为ADT并将其表示为向前关系时,我们将其表示为树列表。试想一下,每个节点只能有一个父节点,但可以有多个子节点。