synonym type not allowed

Arjan van IJzendoorn arjanij@cs.kun.nl
Wed, 17 Dec 1997 10:45:33 +0100


Hello Erik,


>:: MyType :== (Int,Real)
>
>instance == MyType
>where   (==) (i1,r1) (i2,r2)    = i1==i2 && r1==r2
>        (==) _ _                = False
>
>This gives:
>Error [Tryit.icl,17,==]: MyType type synonym used as instance

Type synonyms can not be allowed as instances of type classes.
At least, not as they are now. The problem is that the compiler
can not determine whether the expression (3, 4.0) is of type (Int, Real)
or of your MyType.

For example,

Start = (3,4.0) == (3,5.0)

What should the answer be? Maybe there is yet another type
synonym for (Int, Real) that does not support equality.

:: AnotherType :== (Int, Real) // equality is not defined for this type

For these reasons, type synonyms are not allowed as instances.

Two solutions have been adopted by other languages:
Note that Reals are actually called floats in Haskell and Gofer. But
we can, of course make a type synonym :-)

a) Gofer

   Gofer has so-called "restricted type synonyms". You can limit the
   functions in which the type synonym can be used. In these functions,
   MyType is equal to (Int, Real). In others, they are not. This means
   you have to make explicit constructor functions

   type MyType = (Int, Real) in equalMyType, makeMyType, getMyType

   getMyType :: MyType -> (Int, Real)
   getMyType x = x

   makeMyType :: (Int, Real) -> MyType
   makeMyType x = x

   equalMyType :: MyType -> MyType -> Bool
   equalMyType (i, r) (i, r') = i == i' && r == r'

   instance Eq MyType where
      a == b = equalMyType a b

   Or even shorter:
     instance Eq MyType where
        (==) = equalMyType

b) Haskell (version 1.3 and up, I believe)

   The latest versions of Haskell support the "newtype"-construct.
   I'm not completely sure about the syntax:

   newtype MyType = (Int, Real)

   Now you have to use a "fake" constructor MyType whenever you want
   to construct a value of type MyType, e.g. MyType (3, 5.0). So, in
   a way the line of code defines a type with one constructor with
   one (strict) argument.
   This can, of course, also be done in Clean. However, the advantage of
   the special construct is that the compiler does not generate
   code for the constructor applications. In other words, you don't
   pay for constructing or breaking-down values of this type.

I don't know whether one of these solutions will be adopted in future
versions of Clean.

Greetings,
  Arjan

PS: To Matt: Nijmegen is in the Netherlands.

"..they hung in the sky in much the same way as bricks don't."
                                         -- Douglas Adams --