Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>One more try, inspired by pigworkers post and <a href="http://hackage.haskell.org/packages/archive/representable-functors/3.0.0.1/doc/html/Data-Functor-Representable.html" rel="noreferrer">http://hackage.haskell.org/packages/archive/representable-functors/3.0.0.1/doc/html/Data-Functor-Representable.html</a>.</p> <p>A representable (or Naperian) functor is a comonad itself, if the key (or log) is a monoid! Then <code>coreturn</code> gets the value at position <code>mempty</code>. And <code>cojoin</code> <code>mappend</code>s the two keys it has available. (Just as the comonad instance for <code>(p -&gt;)</code>.)</p> <pre><code>{-# LANGUAGE KindSignatures #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} import Data.List (genericIndex) import Data.Monoid import Data.Key import Data.Functor.Representable data Nat = Z | S Nat data U (n :: Nat) x where Point :: x -&gt; U Z x Dimension :: [U n x] -&gt; U n x -&gt; [U n x] -&gt; U (S n) x dmap :: (U n x -&gt; U m r) -&gt; U (S n) x -&gt; U (S m) r dmap f (Dimension ls mid rs) = Dimension (map f ls) (f mid) (map f rs) instance Functor (U n) where fmap f (Point x) = Point (f x) fmap f d@Dimension{} = dmap (fmap f) d class Functor w =&gt; Comonad w where (=&gt;&gt;) :: w a -&gt; (w a -&gt; b) -&gt; w b coreturn :: w a -&gt; a cojoin :: w a -&gt; w (w a) x =&gt;&gt; f = fmap f (cojoin x) cojoin xx = xx =&gt;&gt; id </code></pre> <p><code>U</code> is representable if the lists are infinitely long. Then there's only one shape. The key of <code>U n</code> is a vector of n integers.</p> <pre><code>type instance Key (U n) = UKey n data UKey (n :: Nat) where P :: UKey Z D :: Integer -&gt; UKey n -&gt; UKey (S n) instance Lookup (U n) where lookup = lookupDefault instance Indexable (U n) where index (Point x) P = x index (Dimension ls mid rs) (D i k) | i &lt; 0 = index (ls `genericIndex` (-i - 1)) k | i &gt; 0 = index (rs `genericIndex` ( i - 1)) k | otherwise = index mid k </code></pre> <p>We need to split the <code>Representable</code> instance up in two cases, one for <code>Z</code> and one for <code>S</code>, because we don't have a value of type <code>U n</code> to pattern match on.</p> <pre><code>instance Representable (U Z) where tabulate f = Point (f P) instance Representable (U n) =&gt; Representable (U (S n)) where tabulate f = Dimension (map (\i -&gt; tabulate (f . D (-i))) [1..]) (tabulate (f . D 0)) (map (\i -&gt; tabulate (f . D i)) [1..]) instance Monoid (UKey Z) where mempty = P mappend P P = P instance Monoid (UKey n) =&gt; Monoid (UKey (S n)) where mempty = D 0 mempty mappend (D il kl) (D ir kr) = D (il + ir) (mappend kl kr) </code></pre> <p>And the key of <code>U n</code> is indeed a monoid, so we can turn <code>U n</code> into a comonad, using the default implementations from the representable-functor package.</p> <pre><code>instance (Monoid (UKey n), Representable (U n)) =&gt; Comonad (U n) where coreturn = extractRep cojoin = duplicateRep (=&gt;&gt;) = flip extendRep </code></pre> <p>This time I did some testing.</p> <pre><code>testVal :: U (S (S Z)) Int testVal = Dimension (repeat (Dimension (repeat (Point 1)) (Point 2) (repeat (Point 3)))) (Dimension (repeat (Point 4)) (Point 5) (repeat (Point 6))) (repeat (Dimension (repeat (Point 7)) (Point 8) (repeat (Point 9)))) -- Hacky Eq instance, just for testing instance Eq x =&gt; Eq (U n x) where Point a == Point b = a == b Dimension la a ra == Dimension lb b rb = take 3 la == take 3 lb &amp;&amp; a == b &amp;&amp; take 3 ra == take 3 rb instance Show x =&gt; Show (U n x) where show (Point x) = "(Point " ++ show x ++ ")" show (Dimension l a r) = "(Dimension " ++ show (take 2 l) ++ " " ++ show a ++ " " ++ show (take 2 r) ++ ")" test = coreturn (cojoin testVal) == testVal &amp;&amp; fmap coreturn (cojoin testVal) == testVal &amp;&amp; cojoin (cojoin testVal) == fmap cojoin (cojoin testVal) </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload