packages feed

signals-0.0.0.1: Backend/Ex.hs

{-# LANGUAGE GADTs         #-}
{-# LANGUAGE TypeOperators #-}

---------------------------------------- Testing
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
----------------------------------------

module Backend.Ex where

import Data.Typeable
import Data.Proxy

---------------------------------------- Testing
import Frontend.Signal (TStruct(..))
----------------------------------------

--------------------------------------------------------------------------------
-- * Existential types
--------------------------------------------------------------------------------

-- | Existential types over containers
data Ex c
  where
    Ex :: Typeable a => c a -> Ex c

-- | Wrapper type for nested containers
newtype (f :*: g) e = T (f (g e))

--------------------------------------------------------------------------------
-- ** Instances

instance Show (Ex c) where show _ = "Ex"

--------------------------------------------------------------------------------
-- ** Helper functinons for generalized existential types

-- | Hides the inner argument, wrapping the types
wrap :: Typeable e => f (g e) -> Ex (f :*: g)
wrap = Ex . T

-- | Retreives the inner type, uses type casting
unwrap :: Typeable e => Ex (f :*: g) -> f (g e)
unwrap (Ex t) = case gcast t of
                  Just (T x) -> x
                  Nothing    -> error "unwrap: type error"

--------------------------------------------------------------------------------
-- * Testing
--------------------------------------------------------------------------------

instance Show (Ex (TStruct e))
  where
    show (Ex s) = showTS s

showTS :: TStruct e a -> String
showTS (TLeaf c) = show c
showTS (TPair l r) = "(" ++ showTS l ++ "," ++ showTS r ++ ")"