How to do store algebraic data type in persistent

haskell, persistent, yesod

Solution

Persistent can only store ADTs that have no child data. I.E. the following can be stored:

data Tag = Leaf | Fork

But recursive structures like this cannot be stored without serialising it to JSON:

data Tree a = (Leaf a) | Fork (Tree a) (Tree a)

What you have to understand is that Persistent is a type save layer over the top of a database, so you have to think about your schema in terms of what is efficient to store in a database, not in terms of what's a convenient Haskell datastructure.

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

This schema will give you the equivalent of the following structure.

data Tree a = Value a [Tree a]

Problem

For a data type like so ``` data Tree = Node String Tree Tree | Leaf String ``` And real data like so ``` my_tree = (Node "first node" (Leaf "leaf") (Node "second node" (Leaf "leaf") (Leaf "leaf"))) ``` How do I store that into database using persistent, specifically how to do the "OR" part? I've tried defining the model like so ``` share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase| Tree value String leftTree Leaf rightTree Leaf deriving Show Leaf value String deriving Show |] ``` The recursive structure would be stored in a column in a row as a json string automatically which is very nice. But how do we or can we define a "OR" structure in the persistent model?

Original source