Idris中guard为何需要Ord类型类?
为什么快排例子里
guard看起来需要Ord? 嘿,我完全懂你的困惑——毕竟看guard的定义,它确实只要求Alternative f约束,和Ord半毛钱关系都没有:
guard : Alternative f => Bool -> f () guard a = if a then pure () else empty
问题的关键在于:不是guard本身需要Ord,而是你在快速排序代码里传给guard的条件需要Ord。
举个具体的例子,在基于列表的快排实现里,你大概率写了类似这样的逻辑:
filterLess : Ord a => List a -> a -> List a filterLess xs pivot = do x <- xs guard (x <= pivot) -- 这里的`x <= pivot`需要`Ord a`约束 pure x
这里的<=运算符是Ord类型类提供的——只有实现了Ord接口的类型,才能使用这类比较操作。guard只是接收这个比较产生的Bool值,它本身不关心这个Bool是怎么来的,但生成这个Bool的比较逻辑必须依赖Ord。
换个场景就能更清楚:如果你的guard条件是完全不涉及比较的,比如guard (length xs == 3),那这里需要的是Eq Nat(因为length返回Nat),而不是Ord;如果是guard True,那甚至不需要任何额外约束。
再回到Alternative接口:它定义的是支持“可选”或“失败”操作的类型(比如列表、Maybe),guard只是利用了它的pure和empty来实现“条件满足就继续,不满足就失败”的逻辑,从头到尾和Ord没有直接关联。
所以你看到的Ord约束,其实是快排逻辑里比较元素大小的需求带来的,和guard本身无关~
内容的提问来源于stack exchange,提问作者bbarker
相关产品推荐
相关产品推荐

