[GHC] #15078: base: Customary type class laws (e.g. for Eq) and non-abiding instances (e.g. Float) should be documented

GHC ghc-devs at haskell.org
Mon Apr 23 01:04:46 UTC 2018


#15078: base: Customary type class laws (e.g. for Eq) and non-abiding instances
(e.g. Float) should be documented
-------------------------------------+-------------------------------------
           Reporter:  sjakobi        |             Owner:  (none)
               Type:  feature        |            Status:  new
  request                            |
           Priority:  normal         |         Milestone:  8.6.1
          Component:  Core           |           Version:  8.4.2
  Libraries                          |
           Keywords:                 |  Operating System:  Unknown/Multiple
       Architecture:                 |   Type of failure:  None/Unknown
  Unknown/Multiple                   |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 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)
 }}}

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15078>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list