数値比較の目的で無限大を使用した場合、それは単純に非常に重要になるデータ構造を実装しようとしています。値は<=maxboundになる可能性があるため、これはmaxBound / minBoundではないことに注意してください。ただし、すべての値は<無限大になります。
絶望?
ではどうでしょう!入力するだけ1/0
で返されることがわかりましたInfinity
!ghci で:
Prelude> 1/0
Infinity
Prelude> :t 1/0
1/0 :: (Fractional t) => t
Prelude> let inf=1/0
Prelude> filter (>=inf) [1..]
そしてもちろん、それは永遠に実行され、無限より大きい数を見つけることはありません. (ただし、 の実際の動作については、以下の ephemient のコメントを参照してください[1..]
)
infinity = read "Infinity"
多分あなたは多分タイプが欲しいですか?
data Infinite a = Infinite | Only a
次に、必要な数値規則を使用して、Num a => Infinite a の Num インスタンスを記述します。
このようなことを試してください。ただし、Num
操作 (+
または など) を取得するには、タイプのインスタンス-
を定義する必要があります。授業でやったように。Num
Infinitable a
Ord
data Infinitable a = Regular a | NegativeInfinity | PositiveInfinity deriving (Eq, Show)
instance Ord a => Ord (Infinitable a) where
compare NegativeInfinity NegativeInfinity = EQ
compare PositiveInfinity PositiveInfinity = EQ
compare NegativeInfinity _ = LT
compare PositiveInfinity _ = GT
compare _ PositiveInfinity = LT
compare _ NegativeInfinity = GT
compare (Regular x) (Regular y) = compare x y
main =
let five = Regular 5
pinf = PositiveInfinity::Infinitable Integer
ninf = NegativeInfinity::Infinitable Integer
results = [(pinf > five), (ninf < pinf), (five > ninf)]
in
do putStrLn (show results)
λ: let infinity = (read "Infinity")::Double
λ: infinity > 1e100
True
λ: -infinity < -1e100
True
私のRangedSetsライブラリを見てください。これはまさにこれを非常に一般的な方法で行います。タイプ「境界a」の値が常に特定の「a」の上または下になるように、「境界」タイプを定義しました。境界は、"AboveAll"、"BelowAll"、"Above x"、"Below x" のいずれかです。
場合によってはチェックする必要があるが、チェックしない場合もある境界条件がある場合は、次のように解決できます。
type Bound a = Maybe a
withinBounds :: (Num a, Ord a) => Bound a -> Bound a -> a -> Bool
withinBounds lo hi v = maybe True (<=v) lo && maybe True (v<=) hi