[Haskell-cafe] Re: generics question 2

Frederik Eaton frederik at a5.repetae.net
Tue Apr 4 06:12:50 EDT 2006


Hi Ralf,

Thanks. I'm sorry, now I think that wasn't the source of my problem. 
What I want to do is specialise not to a specific type like Bool but
to the class of all pairs (a,b). But this causes the compiler to
complain, even for simpler examples:

cast True :: (Typeable a, Typeable b) => Maybe (a,b)

<interactive>:1:0:
    Ambiguous type variable `a' in the constraints:
      `Typeable a' arising from instantiating a type signature at <interactive>:1:0-51
      `Show a' arising from use of `print' at Top level
    Probable fix: add a type signature that fixes these type variable(s)

<interactive>:1:0:
    Ambiguous type variable `b' in the constraints:
      `Typeable b' arising from instantiating a type signature at <interactive>:1:0-51
      `Show b' arising from use of `print' at Top level
    Probable fix: add a type signature that fixes these type variable(s)

Is there a way to solve this, or do I have to avoid polymorphism? I
can use 'toConstr' to find out dynamically if a particular type is a
pair, and then use unsafeCoerce, but I hear that unsafeCoerce is
unsafe.

Frederik

On Mon, Apr 03, 2006 at 05:41:55PM -0700, Ralf Lammel wrote:
> > Hi Ralf,
> > 
> > I'm looking for a function like extT but with more general type:
> > 
> > (t a -> s a) -> (t b -> s b) -> (t a -> s a)
> > 
> > Is there such a thing in the generics library?
> 
> Hi Frederik,
> 
> Not sure how you are exactly going to use such an operation ...
> But here is its implementation anyhow.
> Thanks for the riddle.
> 
> Ralf
> 
> import Data.Generics
> 
> -- Frederik's weird ext operation :-)
> ext' :: (Data (t a), Data (s a), Data (t b), Data (s b))
>      => (t a -> s a) -> (t b -> s b) -> (t a -> s a)
> ext' f g ta = case cast g of
>                Just g' -> g' ta
>                Nothing -> f ta
> 
> -- A generic default
> f (Just x) = [x]
> f Nothing  = []
> 
> -- A type-specific case
> g (Just True)  = [True]
> g (Just False) = []
> g Nothing      = []
> 
> -- A composition using our new type-extension operator
> test :: Data a => Maybe a -> [a]
> test = ext' f g
> 
> -- Let's see whether it works ...
> main = do 
>           print $ test (Just (1::Int))
>           print $ test (Just False)
> 
> 

-- 
http://ofb.net/~frederik/


More information about the Haskell-Cafe mailing list