The following function is pretty straightforward:
test :: Int -> Int
test x = case x of
0 -> 0
1 -> 1
_ -> 2
and indeed, test 0 == 0, test 1 == 1, and test 77 == 2.
The following function is almost as straightforward:
import Data.Ratio
test2 :: Rational -> Int
test2 = case x of
0 -> 0
1 % 2 -> 1
_ -> 2
Loading this code in GHCi gives an error Parse error in pattern: 1 % 2.
What gives? Why can't I pattern-match on rational numbers? I can solve the real-world problem this example came from with guards, but I'm curious why pattern-matching doesn't work.
You can in general not pattern match on functions. That would require computing the inverse, which usually doesn't even exist. You can only match on constructors like
Justor:+: these are recognisable from ordinary functions / infix operators by starting with an uppercase character or a colon.You can pattern match on rationals.
The reason, I suppose, why it's not really recommended to use
:%(and it's hence only exported from an internal module, not fromData.Ratio) is thatRatiovalues are always supposed to be minimal, but:%as a plain constructor doesn't ensure this:In particular, if you'd then actually pattern-match on such an unnormalised fraction, you couldn't be sure to succeed.
In cases like
1%2, you can circumvent the problem by pattern matching on a decimal fraction (finite decimal fractions are unique):Of course, this is perhaps not that nice. In modern Haskell, one could theoretically re-define
:%as a smart pattern synonym:which could then be used as in your original example.
... but frankly, it's probably better to just use
numeratoranddenominatoras they are.