# [Haskell-cafe] Newbie Q: Deriving MyOrd from Eq problem

Dmitri O.Kondratiev dokondr at gmail.com
Wed Jul 26 10:20:22 EDT 2006

```On 7/25/06, Jared Updike <jupdike at gmail.com> wrote:
> > I am trying to derive MyOrd class from Eq (Prelude):
> >
> > class Eq a => MyOrd a where
> >         (%<=), (%>), (%>=) :: a -> a -> Bool
> >         x %<= y = (x < y || x == y)
> >         x %> y =  y < x
> >         x %>= y = (y < x || x == y)
> >
> > Q: What's wrong?  Why 'Ord' gets into play here?
>
> You are using < which is a function on types that instance the class
> Ord, so the compiler is telling you to add (Ord a) to the same place
> you have (Eq a) or don't use < or > or any function in the class Ord.
> You can the prelude and thus the Ord class and make your own < and >
> functions but you can't make them refer to the "real" < and >
> functions without Ord because that is where they live.
>
>   Jared.
> --
> http://www.updike.org/~jared/
> reverse ")-:"
>

-- Ok,  then I can derive MyOrd class directly from Ord:

class Ord a => MyOrd a where
(%<), (%<=), (%>), (%>=) :: a -> a -> Bool
x %< y = x < y
x %<= y = (x < y || x == y)
x %> y =  y < x
x %>= y = (y < x || x == y)

instance (MyOrd a, MyOrd b) => MyOrd (a,b) where
(x1, y1) %< (x2, y2) = (x1 %< x2) && (y1 %< y2)
(x1, y1) %> (x2, y2) = (x1 %> x2) && (y1 %> y2)
(x1, y1) %<= (x2, y2) = (x1 %<= x2) && (y1 %<= y2)
(x1, y1) %>= (x2, y2) = (x1 %>= x2) && (y1 %>= y2)

greaterMyOrd :: (MyOrd (a, b)) => (a, b) -> (a, b) -> Bool
greaterMyOrd (x,y) (z,t) = (x,y) %> (z,t)

-- This should work, right? Yet I get this error message:

ClassTest.hs:39:0:
Non-type variables in constraint: MyOrd (a, b)
(Use -fglasgow-exts to permit this)
In the type signature:
greaterMyOrd :: (MyOrd (a, b)) => (a, b) -> (a, b) -> Bool

-- Notwithstanding :) when i comment out declaration:

-- greaterMyOrd :: (MyOrd (a, b)) => (a, b) -> (a, b) -> Bool

-- program gets compiled and checking type of  'greaterMyOrd' gives:

*ClassTest> :t greaterMyOrd
greaterMyOrd :: (MyOrd (a, b)) => (a, b) -> (a, b) -> Bool

-- which is the same as I tried to declare in the program source.
What is hapenning here?

-- Now, when trying to use function 'greaterMyOrd' I get:

*ClassTest> greaterMyOrd (2, 3) (1, 2)

<interactive>:1:0:
Ambiguous type variable `a' in the constraints:
`MyOrd a' arising from use of `greaterMyOrd' at <interactive>:1:0-11
`Num a' arising from the literal `2' at <interactive>:1:14
Probable fix: add a type signature that fixes these type variable(s)

<interactive>:1:0:
Ambiguous type variable `b' in the constraints:
`MyOrd b' arising from use of `greaterMyOrd' at <interactive>:1:0-11
`Num b' arising from the literal `3' at <interactive>:1:17
Probable fix: add a type signature that fixes these type variable(s)

-- Then I try to declare argument types explicitely and get this:

*ClassTest> greaterMyOrd (2::MyOrd, 3::MyOrd) (1::MyOrd, 2::MyOrd)

<interactive>:1:17:
Class `MyOrd' used as a type
In an expression type signature: MyOrd
In the expression: 2 :: MyOrd
In the first argument of `greaterMyOrd', namely `(2 :: MyOrd, 3 :: MyOrd)'
*ClassTest>

-- I am lost. Please enlight me, what am I doing wrong trying to
create my own class, its instance and then using it.
Thanks !

--
Dmitri O Kondratiev,
dokondr at gmail.com
http://www.geocities.com/dkondr/
```