ekmett / adjunctions

Simple adjunctions
http://hackage.haskell.org/package/adjunctions
Other
44 stars 27 forks source link

Does this exist or belong somewhere? #28

Open Icelandjack opened 7 years ago

Icelandjack commented 7 years ago

Is there a home for this class + associated data family?

A common example of data families

class Key key where
  data TotalMap key :: * -> *
  lookup :: key -> TotalMap key val -> val

with some modification

class Functor (TotalMap key) => Key key where
  data TotalMap key :: Type -> Type
  (¡) :: TotalMap key val -> (key -> val)
  tab :: (key -> val) -> TotalMap key val

can form a Representable functor for any instance of Key

instance Key key => Distributive  (TotalMap key) where
  distribute :: Functor f => f (TotalMap key val) -> TotalMap key (f val)
  distribute = distributeRep

instance Key key => Representable (TotalMap key) where
  type Rep (TotalMap key) = key
  index :: TotalMap key val -> (key -> val)
  index = (¡)
  tabulate :: (key -> val) -> TotalMap key val
  tabulate = tab

Since TotalMap key can be made an instance of all these nice classes

instance Key key => Applicative (TotalMap key) where
  pure :: a -> TotalMap key a
  pure = pureRep
  (<*>) :: TotalMap key (a -> b) -> (TotalMap key a -> TotalMap key b)
  (<*>) = apRep

instance Key key => Monad (TotalMap key) where
  return :: a -> TotalMap key a
  return = pureRep
  (>>=) :: TotalMap key a -> (a -> TotalMap key b) -> TotalMap key b
  (>>=) = bindRep

instance Key key => MonadFix (TotalMap key) where
  mfix :: (a -> TotalMap key a) -> TotalMap key a
  mfix = mfixRep

instance (Key key, Monoid key) => Comonad (TotalMap key) where
  extract :: TotalMap key a -> a
  extract = extractRep
  extend :: (TotalMap key a -> b) -> (TotalMap key a -> TotalMap key b)
  extend  = extendRep

instance Key key => MonadReader key (TotalMap key) where
  ask :: TotalMap key key
  ask   = askRep
  local :: (key -> key) -> (TotalMap key a -> TotalMap key a)
  local = localRep

And we can get any of these instances of Key automatically gets us all these nice things

Key key               :- MonadFix        (TotalMap key)
Key key               :- Applicative     (TotalMap key)
Key key               :- Monad           (TotalMap key)
Key key               :- MonadReader key (TotalMap key)
(Key key, Monoid key) :- Comonad         (TotalMap key)
instance Key Bool where
  data TotalMap Bool val = BoolMap val val deriving Functor
  (¡) :: TotalMap Bool val -> (Bool -> val)
  BoolMap f _ ¡ False = f
  BoolMap _ t ¡ True  = t
  tab :: (Bool -> val) -> TotalMap Bool val
  tab f = BoolMap (f False) (f True)

instance (Key key1, Key key2) => Key (key1, key2) where
  data TotalMap (key1, key2) val = PairMap (TotalMap key1 (TotalMap key2 val))
  (¡) :: TotalMap (key1, key2) val -> ((key1, key2) -> val)
  PairMap keys ¡ (k1, k2) = keys ¡ k1 ¡ k2
  tab :: ((key1, key2) -> val) -> TotalMap (key1, key2) val
  tab f = PairMap $
    tab @key1 $ \key1 ->
    tab @key2 $ \key2 ->
    f (key1, key2)
deriving instance (Key key1, Key key2) => Functor (TotalMap (key1, key2))
Icelandjack commented 7 years ago

The classic

instance Key Natural where
  data TotalMap Natural val = NaturalMap (S.Stream val) deriving (Show, Functor)

  (¡) :: TotalMap Natural val -> (Natural -> val)
  NaturalMap str ¡ nat = str S.!! fromIntegral nat

  tab :: (Natural -> val) -> TotalMap Natural val
  tab f = NaturalMap (S.map f (S.iterate succ 0))

is a Comonad if we define instance Key (Sum Natural). What is the best way to make TotalMap (key1, key2) val an instance of Show?

sjoerdvisscher commented 7 years ago

There's this f.e. https://hackage.haskell.org/package/MemoTrie-0.6.7/docs/Data-MemoTrie.html