通常,您不能对函数进行模式匹配。这将需要计算逆,通常甚至不存在。您只能匹配or之类的构造函数:这些可以通过以大写字符或冒号开头的普通函数/中缀运算符识别。Just
:+
您可以在有理数上进行模式匹配。
import GHC.Real (:%)
test2 :: Rational -> Int
test2 = case x of
0 -> 0
1 :% 2 -> 1
_ -> 2
我想,为什么不真正推荐使用:%
它(因此它只从内部模块导出,而不是从 导出Data.Ratio
)的原因是Ratio
值总是应该是最小的,但:%
作为一个普通的构造函数并不能确保这一点:
Prelude Data.Ratio GHC.Real> 4%2
2 % 1
Prelude Data.Ratio GHC.Real> 4:%2
4 % 2
特别是,如果您实际上在这样一个非规范化的分数上进行模式匹配,您就不能确保成功。
在这种情况下1%2
,您可以通过对小数部分进行模式匹配来规避该问题(有限小数部分是唯一的):
test2 :: Rational -> Int
test2 = case x of
0 -> 0
0.5 -> 1
_ -> 2
当然,这可能不是那么好。在现代 Haskell 中,理论上可以重新定义:%
为智能模式的同义词:
{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
import Data.Ratio
numDenum :: Integral a => Ratio a -> (a,a)
numDenum x = (numerator x, denominator x)
pattern (:%) :: () => Integral a => a -> a -> Ratio a
pattern a:%b <- (numDenum -> (a,b))
where a:%b = a%b
然后可以像在您的原始示例中一样使用它。
...但坦率地说,最好直接使用numerator
和denominator
原样使用。