[Haskell-beginners] containers and extensibility,
typeclasses vs. multiple value constructors
Daniel Fischer
daniel.is.fischer at web.de
Mon Sep 6 09:14:04 EDT 2010
On Monday 06 September 2010 06:47:16, Greg wrote:
> I think I'm starting to get a sense for this, but want to check my
> understanding...
>
> I'm writing a program that plots data. I want to be able to have
> multiple plots simultaneously-- some are scatter plots, some are lines,
> some are functions, etc. I think there are two choices in how to define
> these different plot styles: I can have one type with constructors for
> scatter, line, function, etc; or I can have independent types for each
> plot style and a typeclass to define the shared functionality.
>
> I want to be able to treat these plots abstractly within the program: I
> don't care what style of plot it is at certain levels of processing, I
> just know I want to render it. This suggests a typeclass handling,
> where the typeclass has a render method.
>
> However, I also want to maintain a list of these plots so I can 'mapM_
> render plotlist'. I believe I can only create a list of plots if
> they're all the same type,
Right.
> therefore they must be multiple constructors
> for the same type. 'render' then will need to be handled by pattern
> matching.
Weeeelll,
>
> The last piece of this, is that it would be nice to be able to add new
> plot styles later. Ideally this will all become a library for me, and
> I'd like to be able to add a new plot style without having to modify the
> existing code. I think the only way to do this is through the typeclass
> mechanism, where I can create the new type and create a class instance
> in my local code.
>
> So, am I stuck with this tradeoff? I can either put my plots in a
> container using one type and multiple constructors, or I can make the
> system extensible using typeclasses?
you can combine the approaches. As long as all you want to do with your
container is rendering the contents,
{-# LANGUAGE ExistentialQuantification #-}
class Plot a where
render :: a -> IO ()
describe :: a -> String
data SomePlot = forall p. Plot p => SomePlot p
instance Plot SomePlot where
render (SomePlot p) = render p
describe (SomePlot p) = describe p
gives you a class, so you can define new plot types without modifying the
library, and a wrapper type, so you can stick plots of different types in
the same container after wrapping them.
Once they're wrapped, you can't use anything but the methods of the Plot
class on them, though, so if you want to do anything else with the
container's contents, that won't work (you can do something with an
additional Typeable constraint).
http://www.haskell.org/haskellwiki/Existential_type for more.
>
> Thanks--
> Greg
>
HTH,
Daniel
More information about the Beginners
mailing list