2012-12-15 40 views
5

比方說,我想這樣定義一個樹:棄用-XDatatypeContext的替代方法?

{-# LANGUAGE DatatypeContexts #-} 
class Node a where 
    getContent :: (Num a) => a 

data (Node a) => Tree a = Leaf a 
         | Branch a (Tree a) (Tree a) 

-XDatatypeContexts現在已經過時了。沒有它可以做類似的事情嗎?

回答

13

你是肯定數據類型上下文實際上做了你認爲它做了什麼?這是deprecated because it was basically useless,並被廣泛認爲是錯誤的,因爲它所做的只是強迫你增加額外的約束,而不提供任何超出你沒有的類型的保證。

實際上確實是有用的替代品,例如它是GADT syntax。你的類型的等效是這樣的:

data Tree a where 
    Leaf :: (Node a) => a -> Tree a 
    Branch :: (Node a) => a -> Tree a -> Tree a -> Tree a 

在這種情況下,您在創建Tree值時需要的Node約束,但是當一個Tree價值模式匹配,你還可以得到一個自動保證一個Node實例存在,使得實例可用,而不需要將其作爲接收Tree a作爲參數的函數的類型。

+0

非常感謝!雖然我認爲你的意思是 Branch ::(Node a)=> a - > Tree a - > Tree a – Jake

+0

@Jake:No - 它就像函數類型簽名一樣工作,所以最後一個'Tree a'是結果數據類型。 'a - >樹a - >樹a'只有一個子樹。比較你當前擁有的'Branch'構造函數的類型。 –

+0

哦,對,我明白了。 – Jake

相關問題