
Hi all, I'm designing a ncurses based GUI library. I'm calling smallest GUI elements "widgets". A widget can have internal state of any type. Let's call this type `s`. I want to be able to have something like this:
data Widget s = Widget { handleKey :: Key -> s -> s , draw :: Int -> Int -> Int -> Int -> IO () , getFocus :: s -> s , loseFocus :: s -> s -- more methods may be added in the future }
I also want to be able to have container types like this:
data Container = Container [Widget s]
but obviously this does not work because widgets may have different types of states. So problem I'm trying to solve here is that I should somehow abstract internal state used in a Widget but still be able to keep track of that state so that I can pass it to methods in sequential invocations of that methods. Also, once I have a container like this, updating widget states would become a problem. I'd have to somehow keep all those states like:
data Container = Container [Widget] [WidgetState]
or
data Container = Container [(Widget, WidgetState)]
and then manually pass state to widgets when calling methods, and update the list using return values of methods. In a sense I'm like trying to emulate something like closures with mutable closed-over data in impure languages. I think one way to have a similar effect is to use closures with closed-over IORefs. Then I could modify that state but then I'd need to have methods with types `IO ()`. I want to have more "precise" types. i.e. IO is a lot more general than what I'd like to have as my widget methods. (side effect of a widget should be limited with changes in it's internal state) Sorry for badly organized post, I'm a bit tired right now and I hope my points are clear. I'm trying to figure out Haskell way of doing something like this, without going into IO world. Ideas/suggestions would be appreciated. Thanks, --- Ömer Sinan Ağacan http://osa1.net