[Haskell-cafe] Re: Dynamically find out instances of classes (pluginsystem for haskell)

ChrisK haskell at list.mightyreason.com
Thu Nov 22 13:41:30 EST 2007


Jason Dusek wrote:
> ChrisK <haskell at list.mightyreason.com> wrote:
>> the standard way to do that is use an existential wrapper:
> 
> Does this relate to the "basket of fruit" problem in object
> oriented languages?
> 
> You created the existential wrapper to allow a multimorphic
> list type?
> 

When you access the wrapped data then *_ONLY_* thing you can do with it is via
the type class(es) that the GADT was wrapping.

The example I gave had a single type class:

> data WrapInterface where
>        WrapInterface :: forall z. Interface z => z -> WrapInterface
> 

One could have multiple interfaces:

> data WrapInterface where
>        WrapInterface :: (Interface z,Show z,Num z) => z -> WrapInterface
> 

One could have more than one piece of data, note that WrapInterface takes three
parameters:

> data WrapInterface where
>        WrapInterface :: Interface z => z -> z -> z -> WrapInterface
>

One could do both:
> data WrapInterface where
>   WrapInterface :: (Interface z1, Show z2,Num z3) =>
>                     z1 -> z2 -> z3 -> WrapInterface

And so on.  You can even write something like:> data WrapInterface' where
> WrapInterface' :: a -> (a->String) -> WrapInterface'
> 
> listExample = [ WrapInterface' "Hello" (show . (++ "World"))
>               , WrapInterface' 17 (show . succ)
>               , WrapInterface' True (show . not)
>               ]
> 
> apply :: WrapInterface' -> String
> apply (WrapInterface' item function) = function item
> 
> main = do
>   putStrLn (show (map apply listExample))

Now a WrapInterface' holds item "a" and a function "a->String".  When you unwrap
this in a case statement you can then apply the function to the item to get the
String.  The output in ghci is:

*Main> main
["\"HelloWorld\"","18","False"]

-- 
Chris



More information about the Haskell-Cafe mailing list