Haskell GADT模式匹配的封装
在这种情况下,存在重复的片段:Haskell GADT模式匹配的封装,haskell,refactoring,pattern-matching,gadt,Haskell,Refactoring,Pattern Matching,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 = cas
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'
并在任何地方使用,例如:
insert x (AATree t) = insert2 AATree AATree x t
有没有办法写
insert2
?天真的方法不会进行类型检查。因为您是GADT上的大小写分支,所以可能在大小写表达式的外部不知道aa的整个类型。这意味着您需要为insert2的函数参数提供更高的秩类型,以便它们可以用于aa的任何类型
这需要{-#LANGUAGE Rank2Types}以及insert2的显式类型注释。所需的确切注释取决于您的GADT和insert类型。
看看你的链接代码,我想你想要
insert2 :: (Ord a) =>
(AANode Black (Succ n) a -> b)
-> (forall c. AANode c n a -> b)
-> a -> AANode c n a -> b
您的签名用于交换
相同的和inc
参数,但在其他方面似乎有效。@AndrewC我知道,但这是一个承诺。不过,我正在考虑是否修复那些不是代码错误的东西。我很少对小的编辑有所保留,当人们纠正我的答案时,我非常感激。建议的编辑审阅队列拒绝代码修复的原因是,它的设计不要求审阅者使用技术理解(顺便说一句,钻石版主干预也是如此)。现在,您可以在无需审阅的情况下进行编辑,您可以修复更多内容。对于不同意你的改变的人,总会有回退,但这种情况很少见。尽管如此,我可以尊重您坚持承诺的决定,即使在我看来它适用于建议的编辑。
insert2 :: (Ord a) =>
(AANode Black (Succ n) a -> b)
-> (forall c. AANode c n a -> b)
-> a -> AANode c n a -> b