I've needed something similar in the past. I used it in the reflection library, and its present on its own on hackage as 'tagged'.
http://hackage.haskell.org/packages/archive/tagged/0.0/doc/html/Data-Tagged.html I talked a bit about using it here: http://comonad.com/reader/2009/clearer-reflection/ -Edward Kmett 2010/2/17 Jonas Almström Duregård <jonas.dureg...@gmail.com> > Hi, > > This literate haskell file was intended to be a quick question about a > problem i have been pondering, but it developed into a short > presentation instead. What i want to know is if there is already > something like this (and suggestions for improvement of course). > > >{-#LANGUAGE GeneralizedNewtypeDeriving#-} > > Sometimes i find myself needing to associate a constant with a type > or, more precisely, with a type class instance. Something like this > would be nice: > > class Sized a where > size :: Int > > instance Sized Int where > size = 32 > > Of course this will not work since there is no way of knowing which > instance i refer to when i use "size". A common work-around is to use > a dummy parameter: > > >class SizedDummy a where > > sizeDummy :: a -> Int > > > >instance SizedDummy Int where > > sizeDummy = const 32 > > The size function is typically passed an undefined value. This is not > very pretty, and somewhat unsafe. Another workaround is to define a > newtype with a type parameter. > > >newtype SizeOf a = MkSize {toInt :: Int} > >class SizedNewType a where > > sizeNewType :: SizeOf a > > > >instance SizedNewType Int where > > sizeNewType = MkSize 32 > > If we want the size of a pair to be the sum of it's components, > something like this is needed: > > >instance (SizedNewType a, SizedNewType b) => SizedNewType (a,b) where > > sizeNewType = sizeNewType' sizeNewType sizeNewType where > > sizeNewType' :: SizeOf a -> SizeOf b -> SizeOf (a,b) > > sizeNewType' a b = MkSize $ toInt a + toInt b > > This is way to much code say that "size = size a + size b". A more > general solution can be achieved by making "Int" another type variable > of "SizeOf". I call the resulting type "Related": > > >newtype Related a b = Related {unrelated :: b} deriving > > (Eq,Ord,Show,Read,Bounded,Enum,Fractional,Num, > > Real,Integral,RealFrac,Floating,RealFloat) > > This type is highly reusable and the GeneralizedNewtypeDeriving > language extension is very practical (although the instances could be > written manually). It can also be used as an Identity monad: > > >instance Functor (Related a) where > > fmap f (Related a) = Related $ f a > > > >instance Monad (Related a) where > > return = Related > > (Related a) >>= f = f a > > This allows the Sized class and instances to be specified in a slim > fashion using a familiar monadic interface: > > >class Sized a where > > size :: Related a Int > > > >instance Sized Int where > > size = return 32 > > > >instance (Sized a, Sized b) => Sized (a,b) where > > size = do > > a <- return size :: Sized a => Related (a,b) (Related a Int) > > b <- return size :: Sized b => Related (a,b) (Related b Int) > > return $ unrelated a + unrelated b > > This still requires a lot of type signatures, some additional magic is > required. It is possible to write general versions of the type > signatures above, which allows the following instance definition for > (,,): > > >instance (Sized a, Sized b, Sized c) => Sized (a,b,c) where > > size = do > > a <- on3 size > > b <- on2 size > > c <- on1 size > > return $ a + b + c > > With the derivation of Num, this can be done even more compact: > > >instance (Sized a, Sized b, Sized c, Sized d) => Sized (a,b,c,d) where > > size = on1 size + on2 size + on3 size + on4 size > > The code for the onN functions: > > >rerelate :: Related a b -> Related c b > >rerelate = return . unrelated > > >on1 :: Related a v -> Related (x a) v > >on1 = rerelate > > >on2 :: Related a v -> Related (x a x0) v > >on2 = rerelate > > >on3 :: Related a v -> Related (x a x0 x1) v > >on3 = rerelate > > >on4 :: Related a v -> Related (x a x0 x1 x2) v > >on4 = rerelate > > > Regards, > Jonas Almström Duregård > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe >
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe