在这个code中有重复的片段:
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
?天真的做法不会发生变形。
答案 0 :(得分:6)
由于您在GADT上进行了案例分支,因此可能在案例表达式的外部不知道整个类型的aa。这意味着你需要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