Comment by DanWaterworth

14 years ago

It's possible in Haskell:

  {-# LANGUAGE ExistentialQuantification #-}

  import Data.Maybe
  import Data.Typeable
  import Data.Dynamic

  import Data.Map (Map)
  import qualified Data.Map as M

  data Orderable = forall a. (Ord a, Typeable a) => Orderable a

  instance Eq Orderable where
    (Orderable a) == (Orderable b) =
      case cast b of
        Just b' -> a == b'
        Nothing -> False

  instance Ord Orderable where
    (Orderable a) < (Orderable b) =
      case typeOf a `compare` typeOf b of
        GT -> False
        LT -> True
        EQ -> a == fromJust (cast b)
    a > b = b < a
    a <= b = not (a > b)
    a >= b = not (a < b)

  toOrd :: (Ord a, Typeable a) => a -> Orderable
  toOrd = Orderable

  fromOrd :: (Ord a, Typeable a) => Orderable -> Maybe a
  fromOrd (Orderable a) = cast a

  m1 = M.empty
  m2 = M.insert (toOrd "hello world") (toDyn (4 :: Int)) m1
  m3 = M.insert (toOrd True) (toDyn "foo") m2
  m4 = M.insert (toOrd (5 :: Int)) (toDyn False) m3

  main = print ((fromJust (fromDynamic (fromJust (M.lookup (toOrd "hello world") m4)))) :: Int)