
#15078: base: Customary type class laws (e.g. for Eq) and non-abiding instances (e.g. Float) should be documented -------------------------------------+------------------------------------- Reporter: sjakobi | Owner: Azel Type: feature request | Status: merge Priority: normal | Milestone: 8.6.1 Component: Core Libraries | Version: 8.4.2 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D4736 Wiki Page: | -------------------------------------+------------------------------------- Description changed by sjakobi: Old description:
As beginning Haskellers regularly ask about these laws and instances I think it would be good to have them documented where they are defined.
Here's a first draft of what I have in mind for `Float`'s `Eq` and `Ord` instances:
{{{ -- | Note that in the presence of @NaN@, this instance does not satisfy -- reflexivity: -- -- >>> nan = 0/0 :: Float -- >>> nan == nan -- False -- -- Also note that this instance does not encode structural equality: -- -- >>> 0 == (-0 :: Float) -- True -- >>> recip 0 == recip (-0 :: Float) -- False instance Eq Float where (==) = eqFloat }}}
{{{ -- | Due to the peculiarities of @NaN@, this instance does not satisfy totality: -- -- >>> nan = 0/0 :: Float -- >>> nan <= nan -- False -- -- Another special case with @NaN@ is: -- -- @ -- 'compare' x y -- | 'isNaN' x || 'isNaN' y = 'GT' -- @ -- -- However -- -- @ -- nan > _ = False -- _ > nan = False -- @ -- -- In consequence we also have: -- -- @ -- 'max' x y | 'isNaN' x || 'isNaN' y = x -- 'min' x y | 'isNaN' x || 'isNaN' y = y -- @ -- -- Ignoring @NaN@, @Infinity@ and @-Infinity@ are the respective greatest -- and least elements of 'Float'. instance Ord Float where (F# x) `compare` (F# y) = if isTrue# (x `ltFloat#` y) then LT else if isTrue# (x `eqFloat#` y) then EQ else GT
(F# x) < (F# y) = isTrue# (x `ltFloat#` y) (F# x) <= (F# y) = isTrue# (x `leFloat#` y) (F# x) >= (F# y) = isTrue# (x `geFloat#` y) (F# x) > (F# y) = isTrue# (x `gtFloat#` y) }}}
New description: As beginning Haskellers regularly ask about these laws and instances I think it would be good to have them documented where they are defined. === Documented so far: (in 793902e6891c30150fd3ac1e0e471269a4766780) ==== Classes * `Eq` * `Floating` * `Fractional` * `Integral` * `Num` * `Ord` ==== Non-abiding instances * `CDouble` (shares `Double`'s deficiencies) * `CFloat` (shares `Float`'s deficiencies) * `Complex a` (inherits deficiencies) * `Double`: `Eq`, `Ord`, `Fractional`, `Num` * `Float`: `Eq`, `Ord`, `Fractional`, `Num` * `Ratio a` (inherits deficiencies) * `Natural`: `Num` === TODO: * `RealFrac` -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15078#comment:13 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler