0

how do I create a List (or whatever. Not a Tuple though) that accepts different instances of some typeclass? Specifically, I want to do something like the following:

[labelNew (Just "foo"), buttonNewWithLabel "bar"]

I don’t care for the syntax-sugar, I just want to pass a list of widgets to a function that will pass them to another function which accepts any widgets.

Right now, the purpose is only to get rid of the line-noise, like that

boxPackStart box content1 PackNatural 0
boxPackStart box content2 PackNatural 0
...
boxPackStart box content100 PackNatural 0

should be eg

box <- col PackNatural [content1, content2, ..., content100]

I found some pages mentioning some dynamic lists but stopped reading when it said "not typesafe"

some idiot
  • 191
  • 13
  • What's the problem with just using an ordinary list of [`Widget`s](http://hackage.haskell.org/package/gtk3-0.14.6/docs/Graphics-UI-Gtk-Abstract-Widget.html#t:Widget)? – leftaroundabout Jan 04 '17 at 15:45
  • something like the following? `map (\c -> boxPackStart box c PackNatural 0) [content1, content2, content3]` – mb21 Jan 04 '17 at 16:01

1 Answers1

1

For widgets specifically, you can use

toWidget :: WidgetClass o => o -> Widget

to safely upcast labels and buttons to widgets, as in:

do
    label <- labelNew (Just "foo")
    button <- buttonNewWithLabel "bar"
    col PackNatural [toWidget label, toWidget button]

Other gtk2hs classes have similar casting functions; generally in that package collection, to* is a safe upcast and castTo* is an unsafe downcast.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380