如何简化Haskell中的cmp函数?实现无冗余的统一返回逻辑
简化冗余的
cmp函数实现 你说得太对了——这个cmp函数的冗余确实很扎眼,四个分支做的都是一模一样的事:提取两个End值里的第一个整数,然后比较它们的大小。完全可以把重复的逻辑抽出来,只写一次核心比较逻辑。
方法一:提取辅助函数(最清晰的方案)
先写一个小工具函数,专门从End类型里取出我们要比较的那个整数键:
getKey :: End -> Int getKey (Leftend (k, _)) = k getKey (Rightend (k, _)) = k
然后cmp函数就可以直接复用这个辅助函数,一行搞定所有情况:
cmp :: End -> End -> Ordering cmp e1 e2 = compare (getKey e1) (getKey e2)
这样不管是Leftend和Rightend的哪种组合,都用同一个逻辑处理,彻底消除了冗余。
方法二:直接在cmp内处理(无额外辅助函数)
如果不想多写一个辅助函数,也可以用where块配合case表达式把提取逻辑内联进去,不过可读性稍弱一点:
cmp :: End -> End -> Ordering cmp e1 e2 = compare k1 k2 where k1 = case e1 of Leftend (k, _) -> k Rightend (k, _) -> k k2 = case e2 of Leftend (k, _) -> k Rightend (k, _) -> k
额外提醒:和默认Ord实例的差异
要注意你已经给End派生了Ord实例,Haskell默认的Ord行为会先比较构造器的顺序(比如Leftend _会被认为小于Rightend _,因为Leftend在数据定义里先出现),但你的自定义cmp函数完全忽略了构造器类型,只看第一个整数。这两种逻辑是不同的,如果你确实需要的是后者,那上面的简化方案就完全匹配你的需求。
内容的提问来源于stack exchange,提问作者user132603
相关产品推荐
相关产品推荐

