From: Marco Túlio Gontijo e Silva <marcot@ho...>  20090423 00:24:10

Hello, I thought it would be good to have ListStore to be an instance of a class like MArray. What I wanted was to be able to use mapArray, but being possible to use the other functions sounded good to me. I thought about writing the instance in the top of the functions defined for ListStore, but they aren't general enough, cause they're indexed with Int starting from 0, and not with Ix i => (i, i). So I searched for a type like the one in MArray, without Ix: Monad m => (e > m e) > a e > m (a e). I found, in the vector package, the MVector type class, but I still thought it would be better to make the implementation of ListStore more generic in gtk2hs, so that it could be used with MArray. What do you think? Greetings.  marcot http://marcot.iaaeee.org/ 
From: Axel Simon <Axel.S<imon@en...>  20090423 07:32:40

On Apr 23, 2009, at 2:05, Marco Túlio Gontijo e Silva wrote: > Hello, > > I thought it would be good to have ListStore to be an instance of a > class like MArray. What I wanted was to be able to use mapArray, but > being possible to use the other functions sounded good to me. > > I thought about writing the instance in the top of the functions > defined > for ListStore, but they aren't general enough, cause they're indexed > with Int starting from 0, and not with Ix i => (i, i). So I searched > for a type like the one in MArray, without Ix: Monad m => (e > m > e) > > a e > m (a e). I found, in the vector package, the MVector type > class, > but I still thought it would be better to make the implementation of > ListStore more generic in gtk2hs, so that it could be used with > MArray. > > What do you think? > Yes, I think that is a reasonable request. In fact, since Pixbuf already requires MArray types, we might as well define these instances in Gtk2Hs itself. This won't easily work on the TreeStore. Furthermore, the functions in ListStore are mostly imperative (in the IO monad), so I don't know if they can be made an instance of MArray. Cheers, Axel. 
From: Marco Túlio Gontijo e Silva <marcot@ho...>  20090507 00:14:43

Hello, Em Qui, 20090423 às 09:32 +0200, Axel Simon escreveu: > On Apr 23, 2009, at 2:05, Marco Túlio Gontijo e Silva wrote: > > I thought it would be good to have ListStore to be an instance of a > > class like MArray. > > I don't know if they can be made an instance of MArray. I think you're right, MArray is not the right interface for dealing with ListStores. I think it should be something that deals with a value in the context, and will stay there, like IORef. I've made the following code about it: \begin{code} module Control.Context (Context (..), Functor (..), Foldable (..), Fold (..)) where import Prelude hiding (Functor, fmap, foldr, foldl) import qualified Prelude as P  base import Control.Applicative import Control.Monad.ST import qualified Data.Foldable as F import Data.IORef import Data.Maybe import Data.Monoid import Data.STRef class Context context where type ContextType context :: * > * instance Context (IORef value) where type ContextType (IORef value) = IO instance Context (STRef state value) where type ContextType (STRef state value) = ST state class Context functor => Functor functor value where fmap :: (value > value) > functor > ContextType functor () instance Functor (IORef value) value where fmap = flip modifyIORef instance Functor (STRef state value) value where fmap = flip modifySTRef  Unfortunately I could not generalize this because of the way  IncoherentInstances work. instance (P.Functor functor) => Functor (IORef (functor value)) value where fmap = fmap . (P.fmap :: (value > value) > functor value > functor value) instance (P.Functor functor) => Functor (STRef state (functor value)) value where fmap = fmap . (P.fmap :: (value > value) > functor value > functor value) class (Context foldable, Applicative (ContextType foldable)) => Foldable foldable value where foldMap :: Monoid monoid => (value > monoid) > foldable > ContextType foldable monoid foldMap f = foldr (mappend . f) mempty foldr :: (value > result > result) > result > foldable > ContextType foldable result foldr function value foldable = flip appEndo value <$> foldMap (Endo . function) foldable foldl :: (result > value > result) > result > foldable > ContextType foldable result foldl function value foldable = flip appEndo value <$> getDual <$> foldMap (Dual . Endo . flip function) foldable foldr1 :: (value > value > value) > foldable > ContextType foldable value foldr1 function foldable = fromMaybe (error "foldr1: empty structure") <$> foldr apply Nothing foldable where apply first Nothing = Just first apply first (Just second) = Just $ function first second foldl1 :: (value > value > value) > foldable > ContextType foldable value foldl1 function foldable = fromMaybe (error "foldl1: empty structure") <$> foldl apply Nothing foldable where apply Nothing second = Just second apply (Just first) second = Just $ function first second instance (F.Foldable foldable) => Foldable (IORef (foldable value)) value where foldMap function ioRef = F.foldMap function <$> readIORef ioRef class (Foldable fold value, Monoid value) => Fold fold value where fold :: fold > ContextType fold value fold = foldMap id class Context traversable => Traversable traversable value where traverse :: (value > ContextType traversable value) > traversable > ContextType traversable () instance T.Traversable traversable => Traversable (IORef (traversable value)) value where traverse function ioRef = readIORef ioRef >>= T.mapM function >>= writeIORef ioRef instance T.Traversable traversable => Traversable (STRef state (traversable value)) value where traverse function stRef = readSTRef stRef >>= T.mapM function >>= writeSTRef stRef \end{code} This was the best interface I could think of. The instance for ListStore would go as: \begin{code} instance C.Context (ListStore value) where type C.ContextType (ListStore value) = IO instance C.Functor (ListStore value) value where fmap function listStore = listStoreGetSize listStore >>= listStoreFmap function listStore listStoreFmap :: (value > value) > ListStore value > Int > IO () listStoreFmap _function _listStore 0 = return () listStoreFmap function listStore size = listStoreGetValue listStore index >>= listStoreSetValue listStore index . function >> listStoreFmap function listStore index where index :: Int index = pred size instance C.Foldable (ListStore value) value where foldMap function listStore = foldMap function <$> listStoreToList listStore instance C.Traversable (ListStore value) value where traverse function listStore = listStoreGetSize listStore >>= listStoreTraverse function listStore listStoreTraverse :: (value > IO value) > ListStore value > Int > IO () listStoreTraverse _function _listStore 0 = return () listStoreTraverse function listStore size = listStoreGetValue listStore index >>= function >>= listStoreSetValue listStore index where index :: Int index = pred size \end{code} What do you think about that? Greetings.  marcot http://marcot.iaaeee.org/ 