content: {-# LANGUAGE PolyKinds #-}
  {-# LANGUAGE TypeFamilies #-}
  {-# LANGUAGE TypeOperators #-}
  {-# LANGUAGE DefaultSignatures #-}
  {-# LANGUAGE NoImplicitPrelude #-}
  --------------------------------------------------------------------
  -- |
  -- Copyright :  (c) Edward Kmett 2008-2014
  -- License   :  BSD3
  -- Maintainer:  Edward Kmett <ekmett@gmail.com>
  -- Stability :  experimental
  -- Portability: non-portable
  --
  --------------------------------------------------------------------
  module Hask.Store where
  
  import Hask.Core
  
  -- more general indexing is possible. how should we explore them?
  
  type family Store :: i -> i -> i
  
  data Store0 s a = Store (s -> a) s
  type instance Store = Store0
  
  instance Functor (Store0 s) where
    fmap f (Store g s) = Store (f . g) s
  
  instance Cosemimonad (Store0 s) where
    duplicate (Store f s) = Store (Store f) s
  
  instance Comonad (Store0 s) where
    extract (Store f s) = f s
  
  -- indexed store
  data Store1 s a i = Store1 (s ~> a) (s i)
  type instance Store = Store1
  
  instance Functor (Store1 s) where
    fmap f = Nat $ \(Store1 g s) -> Store1 (f . g) s
  
  instance Cosemimonad (Store1 s) where
    duplicate = Nat $ \(Store1 f s) -> Store1 (Nat $ Store1 f) s
  
  instance Comonad (Store1 s) where
    extract = Nat $ \(Store1 f s) -> transport f s
  