问题描述:

So I am playing around with Haskell and noticed something which puzzles me. I defined a complex floating point data structure and wanted to used comparison operators on it. Initally I did this which worked fine:

`data Cplx = Cplx Float Float deriving (Eq, Show)`

instance Ord Cplx where

(<=) a b = (<=) (normCplx a) (normCplx b)

(>=) a b = (>=) (normCplx a) (normCplx b)

(<) a b = (<) (normCplx a) (normCplx b)

(>) a b = (>) (normCplx a) (normCplx b)

normCplx :: Cplx -> Float

normCplx (Cplx a1 a2) = sqrt( a1^2 + a2^2)

But I also noticed just declaring:

`data Cplx = Cplx Float Float deriving (Eq, Show)`

instance Ord Cplx where

(<=) a b = (<=) (normCplx a) (normCplx b)

normCplx :: Cplx -> Float

normCplx (Cplx a1 a2) = sqrt( a1^2 + a2^2)

Also got the job done just fine. How does Haskell infer the definitons for the other comparison operators given only the single definition?

Thanks!

the rest is implemented just with the type-class using `(<=)`

(or `compare`

) - this is what "minimal implementation" in the docs here: http://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Ord mean.

Minimal complete definition: either compare or <=. Using compare can be more efficient for complex types.

Sadly in this case you cannot show the source directly from Hackage but as `Ord a`

implies `Eq a`

it's not hard to imagine how this is done.

For example as you have `(<=)`

implemented `(<)`

can just be:

```
a < b = a /= b && a <= b
```

with that you get

```
a >= b = not (a < b)
```

and finaly

```
a > b = not (a <= b)
```

or something similar.

Btw as you might have seen in your first implementation you did not implement `compare`

, `max`

or `min`

even if it's part of the type-class and this it got infered too.

Maybe you can try to guess it yourself.

David found the sources - here is the implementation right from there:

```
class (Eq a) => Ord a where
compare :: a -> a -> Ordering
(<), (<=), (>), (>=) :: a -> a -> Bool
max, min :: a -> a -> a
compare x y = if x == y then EQ
-- NB: must be '<=' not '<' to validate the
-- above claim about the minimal things that
-- can be defined for an instance of Ord:
else if x <= y then LT
else GT
x < y = case compare x y of { LT -> True; _ -> False }
x <= y = case compare x y of { GT -> False; _ -> True }
x > y = case compare x y of { GT -> True; _ -> False }
x >= y = case compare x y of { LT -> False; _ -> True }
-- These two default methods use '<=' rather than 'compare'
-- because the latter is often more expensive
max x y = if x <= y then y else x
min x y = if x <= y then x else y
{-# MINIMAL compare | (<=) #-}
```

As you can see: if you have `compare`

or `(<=)`

all else follows.

It must be said that the `Ord`

typeclass is for types with *total order*, and complex numbers do not satisfy the properties of total order. In particular, your implementation violates the *anti-symmetry* property, that is,

```
forall a b. if a ≤ b and b ≤ a then a = b.
```

Failing to satisfy this property violates the contract of `Ord`

and could result in strange bugs, depending on how the instance is used.

It might be more appropriate to apply `normCplx`

where you might have relied on functionality derived from `Ord`

, e.g., `sortBy (compare `on` normCplx)`

where you might have just used `sort`

.

您可能感兴趣的文章：

- restructuredtext - How can I display externally hosted images in my Sphinx (reStructured Text) document?
- c++ - Managing a Contiguous Chunk of Memory without Malloc/New or Free/Delete
- sublimetext - Using regex in Find/Replace to replace multiple matches
- ios - Unable to run app in simulator
- sql server 2008 r2 - Modify table name at runtime
- php - Reading a specific line from a text file
- clr - Any implementation of an Unrolled Linked List in C#?
- Finding Hudson Log Files
- Forward to a payment-gateway together with POST data using cURL (or any other PHP server side solution)
- WCF in Winforms app - is it always single-threaded?

随机阅读：

**推荐内容**-

**热点内容**