On 10/26/05, Tomasz Zielonka <[EMAIL PROTECTED]> wrote:
> See code in the attachment.

I forgot to attach it :-)

Best regards
Tomasz
{-# OPTIONS -fglasgow-exts #-}

module Type where

import Control.Monad

data Type t where
    Bool    :: Type Bool
    Int     :: Type Int
    Char    :: Type Char
    Unit    :: Type ()
    List    :: Type a -> Type [a]
    Pair    :: Type a -> Type b -> Type (a, b)
    Fun     :: Type a -> Type b -> Type (a -> b)

instance Show (Type t) where
    show Bool = "Bool"
    show Int = "Int"
    show Char = "Char"
    show Unit = "()"
    show (List a) = "[" ++ show a ++ "]"
    show (Pair a b) = "(" ++ show a ++ ", " ++ show b ++ ")"
    show (Fun a b) = "(" ++ show a ++ " -> " ++ show b ++ ")"

class Typed t where
    typeOf :: t -> Type t

instance Typed Bool                         where typeOf _ = Bool
instance Typed Int                          where typeOf _ = Int
instance Typed Char                         where typeOf _ = Char
instance Typed ()                           where typeOf _ = Unit
instance Typed a => Typed [a]               where typeOf x = List (typeOf (head x))
instance (Typed a, Typed b) => Typed (a, b) where
    typeOf ~(a,b) = Pair (typeOf a) (typeOf b)
instance (Typed a, Typed b) => Typed (a->b) where
    typeOf _ = Fun (typeOf (undefined :: a)) (typeOf (undefined :: b))

cast :: (Typed a, Typed b) => a -> Maybe b
cast a = cast0 (typeOf a) (typeOf (undefined :: b)) a

newtype Wrapper1 f tc a    = Wrapper1 (f (tc a))

newtype Wrapper21 f tc a b = Wrapper21 (f (tc a b))
newtype Wrapper22 f tc b a = Wrapper22 (f (tc a b))

cast1 :: MonadPlus m => (Type a) -> (Type b) -> f a -> m (f b)
cast1 Bool        Bool          x = return x
cast1 Int         Int           x = return x
cast1 Char        Char          x = return x
cast1 Unit        Unit          x = return x
cast1 (List a)    (List b)      x = do
    Wrapper1 y <- cast1 a b (Wrapper1 x)
    return y
cast1 (Pair a1 b1) (Pair a2 b2) x = cast1TC2 a1 b1 a2 b2 x
cast1 (Fun a1 b1) (Fun a2 b2)   x = cast1TC2 a1 b1 a2 b2 x
cast1 _         _               _ = mzero

cast1TC2 :: MonadPlus m =>
            Type a -> Type b1 -> Type b2 -> Type b -> f (tc a b1) -> m (f (tc b2 b))
cast1TC2 a1 b1 a2 b2 x = do
    Wrapper21 x' <- cast1 b1 b2 (Wrapper21 x)
    Wrapper22 x'' <- cast1 a1 a2 (Wrapper22 x')
    return x''

newtype Id a = Id { unId :: a }

cast0 :: MonadPlus m => (Type a) -> (Type b) -> a -> m b
cast0 ta tb x = liftM unId (cast1 ta tb (Id x))

data Dyn = forall a. Typed a => Dyn a

fromDyn :: Typed a => Dyn -> Maybe a
fromDyn (Dyn d) = cast d

toDyn :: Typed a => a -> Dyn
toDyn a = Dyn a

withDyn :: Dyn -> (forall a. Typed a => a -> b) -> b
withDyn (Dyn d) f = f d

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to