<div dir="ltr">For what it's worth, I'd just like to see a no-nonsense <div><br></div><div><font face="monospace">dup : a -> (a,a)</font></div><div><font face="monospace">dup a = (a,a)</font></div><div><br></div><div>in <font face="monospace">Data.Tuple</font>, where it is out of the way, but right where you'd expect it to be when looking for something for working with tuples.</div><div><br></div><div>Yes, <font face="monospace">bipure</font> and <font face="monospace">id &&& id</font> exist, and generalize it on two incompatible axes, and if we had a proper cartesian category we'd be able to supply this in full generality, as a morphism to the diagonal functor, but all of these require a level of rocket science to figure out.</div><div><br></div><div>I'd also happily support adding the equivalent in <font face="monospace">Data.Either</font> for <font face="monospace">Either a a -> a</font>, which invites bikeshedding names.</div><div><br></div><div>-Edward</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Sep 16, 2020 at 6:10 PM Emily Pillmore <<a href="mailto:emilypi@cohomolo.gy">emilypi@cohomolo.gy</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div><div><div style="display:none;border:0px;width:0px;height:0px;overflow:hidden"><img src="https://r.superhuman.com/0Wx-exEsht6lpb99fo4UQiWIkL98SYOEzLJUv1QFFhli5bllkNoHDBLsayQDodhx8cUxnSyJTqe7dnp6-rT9qAIxGYEoTGbjxFniaPkNXNYPNGwW28U3w7OH-Ha5dqTJNOY5Lv3a8yLSaZJO9r_ZF2xLtuAYQQTH7MWHJvQSHLQU2hbjV-rdY8M.gif" alt="" width="1" height="0" style="display: none; border: 0px; width: 0px; height: 0px; overflow: hidden;"></div><div><div><div>Just to clarify, that's not the "real" diagonal in the space, but it is a super useful translation that I'd like for free :)</div></div><br><div></div></div><br><div><div class="gmail_quote">On Wed, Sep 16, 2020 at 9:08 PM, Emily Pillmore <span dir="ltr"><<a href="mailto:emilypi@cohomolo.gy" target="_blank">emilypi@cohomolo.gy</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail_extra"><div class="gmail_quote" id="gmail-m_7220689800887981291null"><div><div><div><div>@Asad that's a perfectly reasonable way to think about diagonal operations: as the data of a cartesian monoidal category, and the laws are correct in this case. I think we can get away with the additional abstraction to `Biapplicative` in this case, though.<br></div><div><br></div><blockquote><div style="text-decoration:none"><div style="text-decoration:none"><div><div><div><div><div><div><div><p style="margin:0px">wouldn't the existence of appropriate `forall a. a -> t a a` and `forall a. x -> Unit t` functions pigeonhole it into being "the" cartesian monoidal structure on `->` (and thus naturally isomorphic to `(,)`)?<br></p></div></div></div></div></div></div></div></div></div></blockquote><div><div><br></div><div>Only if you chose that particular unit and that particular arrow. But there are other places where having a general `Biapplicative` contraint would make it useful. For example,  i'd like to use this in `smash` with `diag :: a → Smash a a`, defining the adjoining of a point to `a` and creating a diagonal in the subcategory of pointed spaces in Hask, so that I don't have to redefine this as `diag' = quotSmash . view _CanIso . diag . Just`. <br></div><div><br></div><div>Cheers,<br></div><div>Emily</div><div><br></div><div><br></div><div><br></div><div><br></div></div><div><br></div></div><br><div></div></div><br><div><div class="gmail_quote">On Wed, Sep 16, 2020 at 6:35 PM, Asad Saeeduddin <span dir="ltr"><<a href="mailto:masaeedu@gmail.com" rel="noopener noreferrer" target="_blank">masaeedu@gmail.com</a>></span> wrote:<br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote"><div class="gmail_extra"><div id="gmail-m_7220689800887981291null" class="gmail_quote"><p>Whoops, I just realized I've been responding to Carter
      specifically instead of to the list.<br>
      <br>
      I was having some trouble understanding the `unJoin` stuff but I
      read it a few more times and I think I understand it a little
      better now.<br>
      <br>
      In my personal experience the "abstracted version" of `x -> (x,
      x)` I use most often looks like this:<br>
      <br>
      ```<br>
    </p>
    <pre>class SymmetricMonoidal t i p => CartesianMonoidal t i p</pre>
    <pre>  where</pre>
    <pre>  duplicate :: p x (x `t` x)</pre>
    <pre>  discard :: p x i

</pre>
    <pre>-- Laws:</pre>
    <pre>-- duplicate >>> first  discard = fwd lunit</pre>
    <pre>-- duplicate >>> second discard = fwd runit

</pre>
    <pre>-- where</pre>
    <pre>-- lunit :: Monoidal t i p => Iso p x (i `t` x)</pre>
    <pre>-- runit :: Monoidal t i p => Iso p x (x `t` i)</pre>
    <p>```<br>
      <br>
      i.e. adding a suitable duplicate and discard to some symmetric
      monoidal structure gives us a cartesian monoidal structure.<br>
      <br>
      This doesn't really seem to be relevant to what you folks are
      looking for, but it does bring up a question. If some `Bifunctor`
      `t` happens to form a monoidal structure on `->`, wouldn't the
      existence of appropriate `forall a. a -> t a a` and `forall a.
      x -> Unit t` functions pigeonhole it into being "the" cartesian
      monoidal structure on `->` (and thus naturally isomorphic to
      `(,)`)?</p>
    <div>On 9/16/20 5:26 PM, Emily Pillmore
      wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div>
        <div>
          
          <div>
            <div>
              <div>Nice! <br>
                <br>
                That's kind of what I was going for with Carter earlier
                in the day, thanks Matthew. </div>
              <div><br>
              </div>
              <div>I think a diagonalization function and functor are
                both very sensible additions to `bifunctors` and
                `Data.Bifunctor`. The theory behind this is sound: The
                diagonalization functor Δ: Hask → Hask^Hask, forms the
                center of the adjoint triple `colim -| Δ -| lim : Hask →
                Hask^Hask`. <br>
                <br>
                Certainly the function `diag :: a → (a,a)` is something
                I've seen written in several libraries, and should be
                included in `Data.Tuple` as a `base` function. The clear
                generalization of this function is `diag ::
                Biapplicative f ⇒ a → f a a`. I'm in favor of both
                existing in their separate capacities. </div>
              <div><br>
              </div>
              <div>Thoughts? <br>
              </div>
              <div><br>
              </div>
              <div>Emily</div>
            </div>
            <br>
          </div>
          <br>
          <div>
            <div class="gmail_quote">On Wed, Sep 16, 2020 at 3:49 PM,
              Carter Schonwald <span dir="ltr"><<a rel="noopener noreferrer" href="mailto:carter.schonwald@gmail.com" target="_blank">carter.schonwald@gmail.com</a>></span>
              wrote:<br>
              <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                <div class="gmail_extra">
                  <div class="gmail_quote" id="gmail-m_7220689800887981291null">
                    <div dir="auto">Is
                      the join bipure definition taking advantage of the
                      (a->) monad instance?  Slick!</div>
                    <div dir="auto"><br>
                    </div>
                    <div dir="auto"><br>
                    </div>
                    <div>
                      <div class="gmail_quote">
                        <div class="gmail_attr" dir="ltr">On Wed, Sep 16, 2020 at 3:39 PM
                          Matthew Farkas-Dyck <<a href="mailto:strake888@gmail.com" rel="noopener noreferrer" target="_blank">strake888@gmail.com</a>>
                          wrote:<br>
                        </div>
                        <blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">We also have<br>
                          <br>
                          <br>
                          <br>
                          diag = join bipure<br>
                          <br>
                          <br>
                          <br>
                          and (in pseudo-Haskell)<br>
                          <br>
                          <br>
                          <br>
                          diag = unJoin . pure<br>
                          <br>
                            where<br>
                          <br>
                              newtype Join f a = Join { unJoin :: f a a
                          } deriving (Functor)<br>
                          <br>
                              deriving instance Biapplicative f =>
                          Applicative (Join f)<br>
                          <br>
                          <br>
                          <br>
                          The latter seems on its face potentially
                          related to the instance for<br>
                          <br>
                          lists of fixed length, but i am not sure how
                          deep the connection may<br>
                          <br>
                          be.<br>
                          <br>
                        </blockquote>
                      </div>
                    </div>
                    <p>_______________________________________________
                      <br>
                      Libraries mailing list
                      <br>
                      <a rel="noopener noreferrer" href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a>
                      <br>
                      <a rel="noopener noreferrer" href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a></p>
                  </div>
                </div>
              </blockquote>
            </div>
          </div>
          <br>
        </div>
      </div>
      <br>
      <fieldset></fieldset>
      <pre>_______________________________________________
Libraries mailing list
<a rel="noopener noreferrer" href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a>
<a rel="noopener noreferrer" href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a>
</pre>
    </blockquote>
  


<p>_______________________________________________
<br>
Libraries mailing list
<br>
<a href="mailto:Libraries@haskell.org" rel="noopener noreferrer" target="_blank">Libraries@haskell.org</a>
<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noopener noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a></p></div></div></blockquote></div></div></div></div></div></blockquote></div></div><br></div></div></div>_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></div>