2012-09-04 44 views
2

在這種code存在重複片段相匹配:封裝GADT模式

insert x (AATree t) = case insert' x t of 
    Same t -> AATree t 
    Inc t -> AATree t 

insertBlack :: (Ord a) => a -> AANode Black (Succ n) a -> AnyColor (Succ n) a 
insertBlack x (Black l y r) 
    | x < y  = case insert' x l of 
      Same l' -> AnyColor $ Black l' y r 
      Inc l' -> AnyColor $ skew l' y r 
    | otherwise = case insert' x r of 
      Same r' -> AnyColor $ Black l y r' 
      Inc r' -> AnyColor $ Red l y r' 

所以它試圖寫一個函數:

insert2 same inc x l = case insert' x l of 
      Same aa -> same aa 
      Inc aa -> inc aa 

而且在任何地方使用它,例如:

insert x (AATree t) = insert2 AATree AATree x t 

有沒有辦法寫insert2?幼稚的方法不會檢查。

回答

6

由於您是在GADT上分支的情況,可能整個類型的aa在case表達式的外部是未知的。這意味着你需要insert2的函數參數的更高等級的類型,以便它們可以用於任何類型的事件。

這需要{ - #LANGUAGE Rank2Types# - }以及insert2的顯式類型註釋。所需的確切註釋取決​​於您的GADT並插入'類型。 看着你的鏈接代碼我想你想要的東西像

insert2 :: (Ord a) => 
    (AANode Black (Succ n) a -> b) 
    -> (forall c. AANode c n a -> b) 
    -> a -> AANode c n a -> b 
+0

你的簽名是交換'相同'和'inc'的參數,但它似乎工作。 – nponeccop

+0

@AndrewC我知道,但那是一個承諾。不過,我正在考慮是否修復那些不是代碼錯誤的東西。 –

+0

我很少從小編輯中退縮,當人們糾正我的答案時,我非常感激。建議的編輯審查隊列拒絕代碼修復的原因是,它的設計目的不是要求審閱者使用技術理解(順便說一句,鑽石調解員干預也是如此)。現在,您可以信任未經審覈的編輯,您可以信任修復更多內容。對於不同意你的改變的人總會有回滾,但這很少見。不過,我可以尊重你的決定,即使在我看來它適用於建議的修改,也堅持你的承諾。 – AndrewC