In comp.lang.functional you write:

|> 2) Why can Haskell constructor functions not be overloaded?

|They can. As an example, take the constructor (:+) which makes complex

|numbers. It's defined by

|data (RealFloat a) => Complex a = a :+ a

|and is therefore overloaded for Float and Double and any other type you

|care to give RealFloat instances for.

This wasn't what I meant. I should've been clearer.

Why is the following not reasonable?

--------------------

class Zilch a where

Zero :: a

instance Zilch Float where

Zero = 0.0

instance Zilch Int where

Zero = 0

is_zero :: (Zilch a) => a -> Bool

is_zero Zero = True

is_zero other = False

--------------------

As an example of why this might be useful...

Let's say I'm dealing with some splay trees and some other binary trees.

(Please forgive the factitiousness of the example, but I really did

think of this when doing AVL- and Splay-tree hacking.)

--------------------

-- THE WAY IT IS.

data SplayTree a = SNil | STree (SplayTree a) a (SplayTree a)

data BinTree a = BNil | BTree (BinTree a) a (BinTree a)

class (BinaryTree tree) where

left :: tree a -> tree a

right :: tree a -> tree a

is_empty :: tree a -> Bool

instance (BinaryTree SplayTree) where

left (STree left root right) = left

right (STree left root right) = right

is_empty SNil = True

is_empty (STree _ _ _) = False

instance (BinaryTree BinTree) where

left (BTree left root right) = left

right (BTree left root right) = right

is_empty BNil = True

is_empty (BTree _ _ _) = False

depth :: (BinaryTree tree) => tree a -> Int

depth tree

| is_empty tree =

0

| otherwise =

1 + max (depth (left tree)) (depth (right tree))

--------------------

-- THE WAY IT MIGHT BE.

class BinaryTree tree where

Nil :: tree a

Tree :: tree a -> a -> tree a -> tree a

instance BinaryTree SplayTree where

Nil = SNil

Tree = STree

instance BinaryTree BinTree where

Nil = BNil

Tree = BTree

-- or maybe just:

-- instance BinaryTree SplayTree

-- instance BinaryTree BinTree

depth :: (BinaryTree tree) => tree a -> Int

depth_tree Nil = 0

depth_tree (Tree left root right) =

1 + max (depth left) (depth right)

-- You keep the benefits of pattern-matching, too.

--------------------

Hope this is clearer.

Anyone know a good reason why this couldn't or shouldn't be done?

As I said before; if you view the Haskell numbers 1,2,3,4,... as just a big

enumeration, then they are effectively overloaded nullary constructor

functions.

instance Num Integer where

0 :: Int

1 :: Int

...

instance Num Float where

0 :: Float

1 :: Float

...

1 :: (Num a) => a

Bert.

-----------------------------------------------------------------------

department of computer science university of melbourne

-----------------------------------------------------------------------