Note that there are some explanatory texts on larger screens.

plurals
  1. POWhat is this special functor structure called?
    primarykey
    data
    text
    <p>Suppose that F is an applicative functor with the additional laws (with Haskell syntax):</p> <ol> <li><code>pure (const ()) &lt;*&gt; m</code> === <code>pure ()</code></li> <li><code>pure (\a b -&gt; (a, b)) &lt;*&gt; m &lt;*&gt; n</code> === <code>pure (\a b -&gt; (b, a)) &lt;*&gt; n &lt;*&gt; m</code></li> <li><code>pure (\a b -&gt; (a, b)) &lt;*&gt; m &lt;*&gt; m</code> === <code>pure (\a -&gt; (a, a)) &lt;*&gt; m</code></li> </ol> <p>What is the structure called if we omit (3.)?</p> <p>Where can I find more info on these laws/structures?</p> <h2>Comments on comments</h2> <p>Functors which satisfy (2.) are often called commutative.</p> <p>The question is now, whether (1.) implies (2.) and how these structures can be described. I am especially interested in structures which satisfies (1-2.) but not (3.)</p> <p>Examples:</p> <ul> <li>The reader monad satisfies (1-3.)</li> <li>The writer monad on a commutative monoid satisfies only (2.)</li> <li>The monad <code>F</code> given below satisfies (1-2.) but not (3.)</li> </ul> <p>Definition of <code>F</code>:</p> <pre><code>{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE RankNTypes #-} import Control.Monad.State newtype X i = X Integer deriving (Eq) newtype F i a = F (State Integer a) deriving (Monad) new :: F i (X i) new = F $ modify (+1) &gt;&gt; gets X evalF :: (forall i . F i a) -&gt; a evalF (F m) = evalState m 0 </code></pre> <p>We export only the types <code>X</code>, <code>F</code>, <code>new</code>, <code>evalF</code>, and the instances.</p> <p>Check that the following holds:</p> <ul> <li><code>liftM (const ()) m</code> === <code>return ()</code></li> <li><code>liftM2 (\a b -&gt; (a, b)) m n</code> === <code>liftM2 (\a b -&gt; (b, a)) n m</code></li> </ul> <p>On the other hand, <code>liftM2 (,) new new</code> cannot be replaced by <code>liftM (\a -&gt; (a,a)) new</code>:</p> <pre><code>test = evalF (liftM (uncurry (==)) $ liftM2 (,) new new) /= evalF (liftM (uncurry (==)) $ liftM (\a -&gt; (a,a)) new) </code></pre> <h2>Comments on C. A. McCann's answer</h2> <p>I have a sketch of proof that (1.) implies (2.)</p> <pre><code>pure (,) &lt;*&gt; m &lt;*&gt; n </code></pre> <p>=</p> <pre><code>pure (const id) &lt;*&gt; pure () &lt;*&gt; (pure (,) &lt;*&gt; m &lt;*&gt; n) </code></pre> <p>=</p> <pre><code>pure (const id) &lt;*&gt; (pure (const ()) &lt;*&gt; n) &lt;*&gt; (pure (,) &lt;*&gt; m &lt;*&gt; n) </code></pre> <p>=</p> <pre><code>pure (.) &lt;*&gt; pure (const id) &lt;*&gt; pure (const ()) &lt;*&gt; n &lt;*&gt; (pure (,) &lt;*&gt; m &lt;*&gt; n) </code></pre> <p>=</p> <pre><code>pure const &lt;*&gt; n &lt;*&gt; (pure (,) &lt;*&gt; m &lt;*&gt; n) </code></pre> <p>= ... =</p> <pre><code>pure (\_ a b -&gt; (a, b)) &lt;*&gt; n &lt;*&gt; m &lt;*&gt; n </code></pre> <p>= see below =</p> <pre><code>pure (\b a _ -&gt; (a, b)) &lt;*&gt; n &lt;*&gt; m &lt;*&gt; n </code></pre> <p>= ... =</p> <pre><code>pure (\b a -&gt; (a, b)) &lt;*&gt; n &lt;*&gt; m </code></pre> <p>=</p> <pre><code>pure (flip (,)) &lt;*&gt; n &lt;*&gt; m </code></pre> <p><strong>Observation</strong></p> <p>For the missing part first consider</p> <pre><code>pure (\_ _ b -&gt; b) &lt;*&gt; n &lt;*&gt; m &lt;*&gt; n </code></pre> <p>= ... =</p> <pre><code>pure (\_ b -&gt; b) &lt;*&gt; n &lt;*&gt; n </code></pre> <p>= ... =</p> <pre><code>pure (\b -&gt; b) &lt;*&gt; n </code></pre> <p>= ... =</p> <pre><code>pure (\b _ -&gt; b) &lt;*&gt; n &lt;*&gt; n </code></pre> <p>= ... =</p> <pre><code>pure (\b _ _ -&gt; b) &lt;*&gt; n &lt;*&gt; m &lt;*&gt; n </code></pre> <p><strong>Lemma</strong></p> <p>We use the following lemma:</p> <pre><code>pure f1 &lt;*&gt; m === pure g1 &lt;*&gt; m pure f2 &lt;*&gt; m === pure g2 &lt;*&gt; m </code></pre> <p>implies</p> <pre><code>pure (\x -&gt; (f1 x, f2 x)) m === pure (\x -&gt; (g1 x, g2 x)) m </code></pre> <p>I could prove this lemma only indirectly.</p> <p><strong>The missing part</strong></p> <p>With this lemma and the first observation we can prove</p> <pre><code>pure (\_ a b -&gt; (a, b)) &lt;*&gt; n &lt;*&gt; m &lt;*&gt; n </code></pre> <p>=</p> <pre><code>pure (\b a _ -&gt; (a, b)) &lt;*&gt; n &lt;*&gt; m &lt;*&gt; n </code></pre> <p>which was the missing part.</p> <p><strong>Questions</strong></p> <p>Is this proved already somewhere (maybe in a generalized form)?</p> <h2>Remarks</h2> <p>(1.) implies (2.) but otherwise (1-3.) are independent.</p> <p>To prove this, we need two more examples:</p> <ul> <li>The monad <code>G</code> given below satisfies (3.) but not (1-2.)</li> <li>The monad <code>G'</code> given below satisfies (2-3.) but not (1.)</li> </ul> <p>Definition of <code>G</code>:</p> <pre><code>newtype G a = G (State Bool a) deriving (Monad) putTrue :: G () putTrue = G $ put True getBool :: G Bool getBool = G get evalG :: G a -&gt; a evalG (G m) = evalState m False </code></pre> <p>We export only the type <code>G</code>, <code>putTrue</code>, <code>getBool</code>, <code>evalG</code>, and the <code>Monad</code> instance.</p> <p>The definition of <code>G'</code> is similar to the definition of <code>G</code> with the following differences:</p> <p>We define and export <code>execG</code>:</p> <pre><code>execG :: G' a -&gt; Bool execG (G m) = execState m False </code></pre> <p>We do <strong>not export</strong> <code>getBool</code>.</p>
    singulars
    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.
 

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