Hello! I have a class Drawable, and some datatypes which are instances of it, and I would like to be able to draw them all at once! drawMany window [image, text, otherImage] I think the type of the function drawMany would be: drawMany :: Window -> [forall a. (Drawable a) => a] -> IO () However it doesn't work. I know one solution is to make a new datatype (e.g. DrawableObj) which will be: data DrawableObj = forall a (Drawable a) => DrawableObj a And then declare drawMany as: drawMany :: Window -> [DrawableObj] -> IO () But to use it I have to wrap up myself every drawable in a DrawableObj: drawMany window [DrawableObj image, DrawableObj text, DrawableObj otherImage] Is there another more suitable way to handle a list of drawables? ----- Yves Parès Live long and prosper -- View this message in context: http://old.nabble.com/Lists-of-Existential-DT-tp27735354p27735354.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
Sorry, no luck with that. But you can, probably, define some "customized comma": data DrawPair a b = DrawPair a b (<,>) :: a -> b -> DrawPair a b (<,>) = DrawPair instance (Drawable a, Drawable b) => Drawable (DrawPair a b) where ... drawMany :: Drawable a => Window -> a -> IO () ... drawMany window $ image <,> text <,> otherImage On 28 Feb 2010, at 17:31, Yves Parès wrote:
Hello!
I have a class Drawable, and some datatypes which are instances of it, and I would like to be able to draw them all at once! drawMany window [image, text, otherImage]
I think the type of the function drawMany would be: drawMany :: Window -> [forall a. (Drawable a) => a] -> IO ()
However it doesn't work. I know one solution is to make a new datatype (e.g. DrawableObj) which will be: data DrawableObj = forall a (Drawable a) => DrawableObj a
And then declare drawMany as: drawMany :: Window -> [DrawableObj] -> IO ()
But to use it I have to wrap up myself every drawable in a DrawableObj: drawMany window [DrawableObj image, DrawableObj text, DrawableObj otherImage]
Is there another more suitable way to handle a list of drawables?
----- Yves Parès
Live long and prosper -- View this message in context: http://old.nabble.com/Lists-of-Existential-DT-tp27735354p27735354.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Or like this, with the benefit of using lists. data DrawableObj a = forall a.Drawable a => DrawableObj a a <,> b = DrawableObj a : b drawMany (a<,>b<,>c<,>[]) 2010/2/28 Miguel Mitrofanov <miguelimo38@yandex.ru>:
Sorry, no luck with that.
But you can, probably, define some "customized comma":
data DrawPair a b = DrawPair a b (<,>) :: a -> b -> DrawPair a b (<,>) = DrawPair instance (Drawable a, Drawable b) => Drawable (DrawPair a b) where ... drawMany :: Drawable a => Window -> a -> IO () ... drawMany window $ image <,> text <,> otherImage
On 28 Feb 2010, at 17:31, Yves Parès wrote:
Hello!
I have a class Drawable, and some datatypes which are instances of it, and I would like to be able to draw them all at once! drawMany window [image, text, otherImage]
I think the type of the function drawMany would be: drawMany :: Window -> [forall a. (Drawable a) => a] -> IO ()
However it doesn't work. I know one solution is to make a new datatype (e.g. DrawableObj) which will be: data DrawableObj = forall a (Drawable a) => DrawableObj a
And then declare drawMany as: drawMany :: Window -> [DrawableObj] -> IO ()
But to use it I have to wrap up myself every drawable in a DrawableObj: drawMany window [DrawableObj image, DrawableObj text, DrawableObj otherImage]
Is there another more suitable way to handle a list of drawables?
----- Yves Parès
Live long and prosper -- View this message in context: http://old.nabble.com/Lists-of-Existential-DT-tp27735354p27735354.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
_______________________________________________ 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
-- Eugene Kirpichov Senior Developer, JetBrains
jkff wrote:
Or like this, with the benefit of using lists. data DrawableObj a = forall a.Drawable a => DrawableObj a a <,> b = DrawableObj a : b drawMany (a<,>b<,>c<,>[])
I like this solution, but it's a pity I think that Haskell doesn't provide a way to use types like [forall a. (Drawable a) => a], which obligates you to declare an extra datatype... ----- Yves Parès Live long and prosper -- View this message in context: http://old.nabble.com/Lists-of-Existential-DT-tp27735354p27737144.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
You can actually write that type with impredicative polymorphism, but it doesn't do what you seem to want: it makes a list of polymorphic values (i.e., universally quantified ones, not existentially). But that's going away soon, anyway... On Sun, Feb 28, 2010 at 1:49 PM, Yves Parès <limestrael@gmail.com> wrote:
jkff wrote:
Or like this, with the benefit of using lists. data DrawableObj a = forall a.Drawable a => DrawableObj a a <,> b = DrawableObj a : b drawMany (a<,>b<,>c<,>[])
I like this solution, but it's a pity I think that Haskell doesn't provide a way to use types like [forall a. (Drawable a) => a], which obligates you to declare an extra datatype...
----- Yves Parès
Live long and prosper -- View this message in context: http://old.nabble.com/Lists-of-Existential-DT-tp27735354p27737144.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
drawMany is just sequence dressed up a bit: I assume you have this class: class Drawable a where draw :: Drawable a => a -> Window -> IO () So, the key is to remember that functions and IO actions are first-class values! data Box = ... instance Drawable Box where ... box :: Box box = ... data Circle = ... instance Drawable Circle where ... circle :: Circle circle = ... instance Drawable String where ... with :: b -> [b -> a] -> [a] with w = map ($ w) manyWith :: Monad m => w -> [w -> m a] -> m () manyWith w = sequence . with w sample :: Window -> IO () sample w = manyWith w $ [draw box, draw circle, draw "hello"] On Sun, Feb 28, 2010 at 6:31 AM, Yves Parès <limestrael@gmail.com> wrote:
Hello!
I have a class Drawable, and some datatypes which are instances of it, and I would like to be able to draw them all at once! drawMany window [image, text, otherImage]
I think the type of the function drawMany would be: drawMany :: Window -> [forall a. (Drawable a) => a] -> IO ()
However it doesn't work. I know one solution is to make a new datatype (e.g. DrawableObj) which will be: data DrawableObj = forall a (Drawable a) => DrawableObj a
And then declare drawMany as: drawMany :: Window -> [DrawableObj] -> IO ()
But to use it I have to wrap up myself every drawable in a DrawableObj: drawMany window [DrawableObj image, DrawableObj text, DrawableObj otherImage]
Is there another more suitable way to handle a list of drawables?
----- Yves Parès
Live long and prosper -- View this message in context: http://old.nabble.com/Lists-of-Existential-DT-tp27735354p27735354.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
On Sun, Feb 28, 2010 at 6:31 AM, Yves Parès <limestrael@gmail.com> wrote:
Hello!
I have a class Drawable, and some datatypes which are instances of it, and I would like to be able to draw them all at once! drawMany window [image, text, otherImage]
I think the type of the function drawMany would be: drawMany :: Window -> [forall a. (Drawable a) => a] -> IO ()
However it doesn't work. I know one solution is to make a new datatype (e.g. DrawableObj) which will be: data DrawableObj = forall a (Drawable a) => DrawableObj a
And then declare drawMany as: drawMany :: Window -> [DrawableObj] -> IO ()
But to use it I have to wrap up myself every drawable in a DrawableObj: drawMany window [DrawableObj image, DrawableObj text, DrawableObj otherImage]
Is there another more suitable way to handle a list of drawables?
Luke Palmer has an article on his blog that proposes a different solution to the problem that I believe you're trying to solve: http://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-t... You might give his approach a try and see if it's simpler and easier to work with. Good luck! Jason
participants (6)
-
Daniel Peebles -
Eugene Kirpichov -
Jason Dagit -
Miguel Mitrofanov -
Ryan Ingram -
Yves Parès