如何在Haskell中实现针对非构造函数的模式匹配
解决方案
1. 逆函数模式匹配实现:使用ViewPatterns扩展
你需要的这种非构造函数的模式匹配能力,GHC已经通过ViewPatterns语法扩展提供了,刚好用来突破只能匹配构造函数的限制。
开启扩展后,你的exp和log示例可以写成如下形式:
{-# LANGUAGE ViewPatterns #-} exp :: Double -> Double exp 0 = 1 exp (log -> a) = a -- 其他业务分支 log :: Double -> Double log 1 = 0 log (exp -> a) = a -- 其他业务分支
注意:这种写法要额外补充边界终止条件,避免exp和log互相调用导致无限递归。
2. Monoid结合律规则实现:使用重写规则
你写的Monoid结合律的行,本质是编译期的等式重写需求,不能通过运行时模式匹配实现,应该用GHC的RULES编译指示完成:
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-} class Monoid m where iden :: m (+) :: m -> m -> m -- 单位元匹配逻辑,依赖Eq实例,也可以自己实现判等逻辑替换 (+) a b | a == iden = b | b == iden = a | otherwise = defaultMappend a b -- 结合律重写规则,编译期自动应用无运行时开销 {-# RULES "mappend/associative" forall a b c. ((a + b) + c) = (a + (b + c)) #-}
注意事项
- 所有GHC扩展都需要在文件头部声明,或者编译时通过参数指定
- 运行时的模式匹配会引入额外开销,代数结构的等式优化优先用重写规则在编译期完成
- 逆函数对的模式匹配要注意终止性,避免出现无限递归调用
内容的提问来源于stack exchange,提问作者user13507303
相关产品推荐
相关产品推荐

