2014-02-27 81 views
8

店代數數據類型爲數據類型,像這樣,像這樣如何做到持久

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」結構呢?

+0

如果您的問題需要存儲如此複雜的數據,那麼使用酸態可能會更方便嗎? – user3974391

+0

同上。我正在嘗試從酸性狀態遷移[reffit](http://www.reffit.com)以保存記憶。作爲SQL的新手,我對實際進入數據庫的類型的緊縮感到驚訝。我不得不將所有列表類型的記錄字段都'翻出來'。 – ImAlsoGreg

回答

9

持久性只能存儲沒有子數據的ADT。 I.E.下面可存儲:

data Tag = Leaf | Fork 

但遞歸結構這樣不能儲存,沒有它連載到JSON:

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

你要明白什麼是持久性是一種節約層過頂的數據庫,所以你必須考慮你的模式是根據存儲在數據庫中的效率來衡量的,而不是根據什麼是方便的Haskell數據結構。

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

這個模式會給你以下結構的等價物。

data Tree a = Value a [Tree a] 
+0

你的意思是「沒有遞歸子數據」?所以,例如'data Tag = Leaf Int |叉弦可以存儲? –

+0

@AlexeyRomanov,你知道,我從來沒有嘗試過。我敢打賭,它實際上可以被存儲,儘管它需要首先以某種方式被序列化,並且從我查看持久代碼的那部分開始已經有一段時間了。 – Thomas

+0

是的....我最終明白它只是一個數據庫層。我只是想知道,因爲它足夠聰明可以將其更改爲json,它是否也可以幫助保持數據類型的結構爲「或」?如果是的話如何在模型中定義它?或者就像你寫的那棵樹是一個可能,葉子永遠在那裏? – HHC