一般に、関数のパターンマッチングはできません。それは通常は存在しない逆行列の計算を必要とするでしょう。 のコンストラクタ(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では、1は、理論的にはスマートなパターンの同義語として:%
を再定義することができます。そして、あなたの元の例のように使用することができ
{-# 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
をそのまま使用する方が良いでしょう。
これはちょうどひどく、私はおそらくそれを受け入れるでしょう。しかし、なぜパターンマッチングできないのかという疑問には答えていません(%)。私はパターンマッチングの内部を特によく知っているわけではないので、私が見ていない簡単な答えがあるかもしれません。 – dvitek
そうですね、私はそれをトップに追加しました。 – leftaroundabout
ああ、そうだ。私は '(%)'が実際にはコンストラクタではないことに気付かなかったのですが、 ':info'を見るだけで、明らかにそうではありません。有限小数点法のアプローチは、小数点のデフォルトの「分数a」型の賢明な使用です。これは私が忘れていたものです。 私はスマートパターンの同義語の答えをよく理解していません - 私は恐竜ハスケルを使用していますが、読めるようになっているようです。すばらしい答えの束をありがとう! – dvitek