With IxSet, is it possible to create an indexable wrapper around an arbitrary type of indexing?

What I would like to do is something like the following:

import Data.IxSet

newtype Key a = Key Integer
  deriving (Eq, Ord, Show)

data Keyed a = Keyed { key :: (Key a), value :: a }
  deriving (Eq, Ord, Show)

instance Indexable a => Indexable (Keyed a)
    where empty = ixSet $ ixFun (\k -> [key k]) : _somehow_reuse_indices_of_a_

The idea is that if any data structure is indexable, I should be able to index Keyedby wrapping it with the same types (plus an index on Key a).

It is easy to convert functions passed in ixFunto wrapped-type indexes to work with Keyedinstead a: just compose with value. But I can not find a way to get these functions.

, ixset; Indexable , IxSet. , -, , " " , , , , .

-, ?

+4
1

ixset, , " " "", Indexable , , , . ( , empty , empty !). , , ( ):

data IxFun a = forall key. (Typeable key, Ord key) => IxFun (a -> [key])

ixFun' :: (Typeable key, Ord key) => (a -> [key]) -> IxFun a
ixFun' = IxFun

instance Contravariant IxFun where
    contramap f (IxFun g) = IxFun (g . f)

ixFromIxFun :: IxFun a -> Ix a
ixFromIxFun (IxFun f) = ixFun f

, :

class IndexableFun a where funs :: [IxFun a]

-- turn any IndexableFun into an Indexable
defaultEmpty :: IndexableFun a => IxSet a
defaultEmpty = ixSet (map ixFromIxFun funs)

Indexable, empty = ixSet [ixFun foo, ...] funs = [ixFun' foo, ...]. :

instance (IndexableFun a, Typeable a) => IndexableFun (Keyed a) where
    funs = ixFun' (\v -> [key v]) : map (contramap value) funs

instance (IndexableFun a, Typeable a) => Indexable (Keyed a) where
    empty = defaultEmpty

ixGen :

 ixGen' :: forall proxy a b. (Data a, Ord b, Typeable b) => proxy b -> IxFun a
 ixGen' _ = ixFun' (flatten :: a -> [b])

ixset . , : , -, Indexable, - -, , .

+3

Source: https://habr.com/ru/post/1606546/


All Articles