<div dir="ltr"><div>I agree Foldable1 in base would be great, but I think the most bang for buck would be to include several others; at least also Traversable1 and possibly even Apply,Bind,Alt<br><br></div>I second the comment about the issue related to addressing the names, etc in semigroupoids, in preparation for inclusion to base.<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Oct 18, 2019 at 11:12 AM Oleg Grenrus <<a href="mailto:oleg.grenrus@iki.fi">oleg.grenrus@iki.fi</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 bgcolor="#FFFFFF">
<p>What is the proposed change in semigroupoids, I don't see any
decisive conclusion comment. To get this going, I suggest limiting
discussion to the Foldable1 only<br>
and if after this proposal is accepted, extrapolate for the rest
of `semigroupoids`.<br>
<br>
So if someone can propose a concrete list how to rename symbols in
<a href="http://oleg.fi/haddocks/foldable1/Data-Foldable1.html" target="_blank">https://oleg.fi/haddocks/foldable1/Data-Foldable1.html</a>,
I'll make a separate branch & haddock page.<br>
<br>
Is the wanted renaming s/1//; s/^/semi/:<br>
<br>
<tt>- Foldable1 -> Semifoldable</tt><tt><br>
</tt><tt>- fold1 -> semifold</tt><tt><br>
</tt><tt>- foldMap1 -> semifoldMap</tt><tt><br>
</tt><tt>- foldr1 -> semifoldr</tt><tt><br>
</tt><tt>- foldr1map -> semifoldr1map</tt><tt><br>
</tt><tt>- toNonEmpty -> toNonEmpty</tt><tt><br>
</tt><tt>- ...</tt><tt><br>
</tt><tt>- head1 -> semihead</tt><tt><br>
</tt><tt>- last1 -> semilast</tt><tt><br>
</tt><tt>- minimum1 -> semiminimum</tt><tt><br>
</tt><tt>- maximum1 -> semimaximum</tt><tt><br>
</tt><tt><br>
</tt><tt>- intercalate1 -> semiintercalate</tt><tt><br>
</tt><tt>- foldl1M -> semifoldl</tt><tt><br>
</tt><tt>- ...</tt><tt><br>
</tt><tt>- maximum1By -> semimaximumBy</tt><br>
- ...<br>
<br>
I'm fine with this.<br>
The head1/semihead are both silly, but the suffix was there to
avoid name clash, so prefix is fine for that purpose too.<br>
<br>
---<br>
<br>
The synopsis of current state of proposed Data.Foldable1<br>
<br>
<tt>module Data.Foldable1</tt><tt> where<br>
<br>
</tt><tt>class Foldable t => Foldable1 t</tt><tt><br>
</tt><tt> fold1 :: (Foldable1 t, Semigroup m) => t m
-> m</tt><tt><br>
</tt><tt> foldMap1 :: (Foldable1 t, Semigroup m) => (a ->
m) -> t a -> m</tt><tt><br>
</tt><tt> foldMap1' :: (Foldable1 t, Semigroup m) => (a ->
m) -> t a -> m</tt><tt><br>
</tt><tt> foldr1 :: Foldable1 t => (a -> a -> a)
-> t a -> a</tt><tt><br>
</tt><tt> foldr1' :: Foldable1 t => (a -> a -> a)
-> t a -> a</tt><tt><br>
</tt><tt> foldl1 :: Foldable1 t => (a -> a -> a)
-> t a -> a</tt><tt><br>
</tt><tt> foldl1' :: Foldable1 t => (a -> a -> a)
-> t a -> a</tt><tt><br>
</tt><tt> toNonEmpty :: Foldable1 t => t a -> NonEmpty a</tt><tt><br>
</tt><tt> maximum1 :: forall a. (Foldable1 t, Ord a) => t a
-> a</tt><tt><br>
</tt><tt> minimum1 :: forall a. (Foldable1 t, Ord a) => t a
-> a</tt><tt><br>
</tt><tt> head1 :: Foldable1 t => t a -> a</tt><tt><br>
</tt><tt> last1 :: Foldable1 t => t a -> a</tt><tt><br>
</tt><tt> foldr1map :: Foldable1 t => (a -> b) -> (b
-> b -> b) -> t a -> b</tt><tt><br>
</tt><tt> foldl1'map :: Foldable1 t => (a -> b) -> (b
-> b -> b) -> t a -> b</tt><tt><br>
</tt><tt> foldl1map :: Foldable1 t => (a -> b) -> (b
-> b -> b) -> t a -> b</tt><tt><br>
</tt><tt> foldr1'map :: Foldable1 t => (a -> b) -> (b
-> b -> b) -> t a -> b</tt><tt><br>
</tt><tt><br>
</tt><tt>intercalate1 :: (Foldable1 t, Semigroup m) => m ->
t m -> m</tt><tt><br>
</tt><tt>foldrM1 :: (Foldable1 t, Monad m) => (a -> a
-> m a) -> t a -> m a</tt><tt><br>
</tt><tt>foldlM1 :: (Foldable1 t, Monad m) => (a -> a
-> m a) -> t a -> m a</tt><tt><br>
</tt><tt>maximum1By :: Foldable1 t => (a -> a ->
Ordering) -> t a -> a</tt><tt><br>
</tt><tt>minimum1By :: Foldable1 t => (a -> a ->
Ordering) -> t a -> a</tt></p>
<p>- Oleg<br>
<tt></tt></p>
<div>On 18.10.2019 3.06, Edward Kmett wrote:<br>
</div>
<blockquote type="cite">
I’m happy to take patches to move things along in semigroupoids.
My focus has been elsewhere, I admit.
<div><br>
</div>
<div>-Edward<br>
<div dir="ltr"><br>
<blockquote type="cite">On Oct 17, 2019, at 5:03 PM, Andrew
Martin <a href="mailto:andrew.thaddeus@gmail.com" target="_blank"><andrew.thaddeus@gmail.com></a> wrote:<br>
<br>
</blockquote>
</div>
<blockquote type="cite">
<div dir="ltr">
While I want this abstraction in base, I don’t want it there
yet. There is an open issue on semigroupoids about renaming
everything: <a href="https://github.com/ekmett/semigroupoids/issues/26" target="_blank">https://github.com/ekmett/semigroupoids/issues/26</a>
<div><br>
</div>
<div>This needs to be handled before the abstraction is
brought into base. Also, foldr1 is awful in common
situations. See <a href="https://github.com/ekmett/semigroupoids/issues/77" target="_blank">https://github.com/ekmett/semigroupoids/issues/77</a></div>
<div><br>
</div>
<div>The problem is that refinements of this abstraction
seem to have stalled in semigroupoids, but these are
desperately needed before the abstraction is brought into
base.<br>
<br>
<div id="gmail-m_-829105700172531108AppleMailSignature" dir="ltr">Sent from my iPhone</div>
<div dir="ltr"><br>
On Oct 17, 2019, at 10:42 AM, Oleg Grenrus <<a href="mailto:oleg.grenrus@iki.fi" target="_blank">oleg.grenrus@iki.fi</a>>
wrote:<br>
<br>
</div>
<blockquote type="cite">
<div dir="ltr"><span>I propose adding `Foldable1`
type-class into `base1`.</span><br>
<span></span><br>
<span>Add Foldable1</span><br>
<span>=============</span><br>
<span></span><br>
<span></span><br>
<span>Motivation</span><br>
<span>----------</span><br>
<span></span><br>
<span>It's regularly asked whether `Foldable1` could
be added to `base`</span><br>
<span>(e.g. on reddit[^ref1], there're also GHC
issue[^ref2] and old</span><br>
<span>phabricator diff[^ref3])</span><br>
<span>Also there's work towards non-empty maps and
sets[^ref4],</span><br>
<span>which would benefit from `Foldable1`.</span><br>
<span></span><br>
<span>As commented on reddit, `Foldable1` could be
added without any pain</span><br>
<span>to the `base` as it's pure addition - no
modifications needed in</span><br>
<span>existing modules.</span><br>
<span></span><br>
<span>[^ref1]:</span><br>
<span><a href="https://www.reddit.com/r/haskell/comments/6d0vgt/could_we_have_foldable1_and_traversable1_in_base/" target="_blank">https://www.reddit.com/r/haskell/comments/6d0vgt/could_we_have_foldable1_and_traversable1_in_base/</a></span><br>
<span>[^ref2]: <a href="https://gitlab.haskell.org/ghc/ghc/issues/13573" target="_blank">https://gitlab.haskell.org/ghc/ghc/issues/13573</a></span><br>
<span>[^ref3]: <a href="https://phabricator.haskell.org/D4812" target="_blank">https://phabricator.haskell.org/D4812</a></span><br>
<span>[^ref4]: <a href="https://github.com/haskell/containers/pull/616" target="_blank">https://github.com/haskell/containers/pull/616</a></span><br>
<span></span><br>
<span>Change</span><br>
<span>------</span><br>
<span></span><br>
<span>The change exist as merge request[^ref4] on <a href="http://gitlab.haskell.org" target="_blank">gitlab.haskell.org</a>.</span><br>
<span></span><br>
<span>Importantly, this change **doesn't change**
anything in other modules</span><br>
<span>of `base`, except of adding a `Foldable`
instance to `Data.Complex`.</span><br>
<span>In particular, `foldl1` and `foldr1` in
`Data.Foldable` remain partial, etc.</span><br>
<span></span><br>
<span>My version of `Foldable1` class is big, so I'll
comment the motivation</span><br>
<span>for each member</span><br>
<span></span><br>
<span>```haskell</span><br>
<span>class Foldable t => Foldable1 t where</span><br>
<span> {-# MINIMAL foldMap1 | toNonEmpty |
foldr1map #-}</span><br>
<span></span><br>
<span> -- the defining member, like foldMap but
only asking for Semigroup</span><br>
<span> foldMap1 :: Semigroup m => (a -> m)
-> t a -> m</span><br>
<span></span><br>
<span> fold1 :: Semigroup m => t m -> m#</span><br>
<span></span><br>
<span> -- strict foldMap1, cf foldMap'</span><br>
<span> foldMap1' :: Semigroup m => (a -> m)
-> t a -> m</span><br>
<span></span><br>
<span> -- analogue of toList</span><br>
<span> toNonEmpty :: t a -> NonEmpty a</span><br>
<span></span><br>
<span> -- left&right, strict&non-strict
folds</span><br>
<span> foldr1 :: (a -> a -> a) -> t a
-> a</span><br>
<span> foldr1' :: (a -> a -> a) -> t a
-> a</span><br>
<span> foldl1 :: (a -> a -> a) -> t a
-> a</span><br>
<span> foldl1' :: (a -> a -> a) -> t a
-> a</span><br>
<span></span><br>
<span> -- these can have efficient implementation
for NonEmptySet</span><br>
<span> maximum1 :: forall a. Ord a => t a ->
a</span><br>
<span> minimum1 :: forall a. Ord a => t a ->
a</span><br>
<span></span><br>
<span> -- head1 have efficient implementation for
NonEmpty and Tree</span><br>
<span> -- last1 for symmetry</span><br>
<span> head1 :: t a -> a</span><br>
<span> last1 :: t a -> a</span><br>
<span></span><br>
<span> -- fold variants with premap.</span><br>
<span> -- Without this map, we cannot implement
foldl using foldr etc.</span><br>
<span> foldr1map :: (a -> b) -> (b -> b
-> b) -> t a -> b</span><br>
<span> foldl1'map :: (a -> b) -> (b -> b
-> b) -> t a -> b</span><br>
<span> foldl1map :: (a -> b) -> (b -> b
-> b) -> t a -> b</span><br>
<span> foldr1'map :: (a -> b) -> (b -> b
-> b) -> t a -> b</span><br>
<span>```</span><br>
<span></span><br>
<span>The merge request also adds instances for
everything non-empty in `base`.</span><br>
<span></span><br>
<span>I propose the `Data.Foldable1` as the module
name.</span><br>
<span>`semigroupoids`[^ref6] uses
`Data.Semigroup.Foldable`,</span><br>
<span>but it's confusing; and using different name
could help migration.</span><br>
<span></span><br>
<span>The module contains five top-level functions,
which should</span><br>
<span>be self-explanatory:</span><br>
<span></span><br>
<span>```haskell</span><br>
<span>intercalate1 :: (Foldable1 t, Semigroup m) =>
m -> t m -> m</span><br>
<span></span><br>
<span>foldrM1 :: (Foldable1 t, Monad m) => (a ->
a -> m a) -> t a -> m a</span><br>
<span>foldlM1 :: (Foldable1 t, Monad m) => (a ->
a -> m a) -> t a -> m a</span><br>
<span></span><br>
<span>maximum1By :: Foldable1 t => (a -> a ->
Ordering) -> t a -> a</span><br>
<span>minimum1By :: Foldable1 t => (a -> a ->
Ordering) -> t a -> a</span><br>
<span>```</span><br>
<span></span><br>
<span>This is less than in
`Data.Semigroup.Foldable`[^ref9],</span><br>
<span>as without `Apply` they don't make sense.</span><br>
<span>For example:</span><br>
<span></span><br>
<span>```haskell</span><br>
<span>-- needs Apply, not in Data.Foldable1</span><br>
<span>traverse1_ :: (Foldable1 t, Apply f) => (a
-> f b) -> t a -> f ()</span><br>
<span>```</span><br>
<span></span><br>
<span>And if we relax `Apply` to `Applicative`, we get
`traverse_`.</span><br>
<span> </span><br>
<span>[^ref5]: <a href="https://gitlab.haskell.org/ghc/ghc/merge_requests/1973" target="_blank">https://gitlab.haskell.org/ghc/ghc/merge_requests/1973</a></span><br>
<span>[^ref9]:</span><br>
<span><a href="https://hackage.haskell.org/package/semigroupoids-5.3.3/docs/Data-Semigroup-Foldable-Class.html" target="_blank">https://hackage.haskell.org/package/semigroupoids-5.3.3/docs/Data-Semigroup-Foldable-Class.html</a></span><br>
<span></span><br>
<span>[^ref5]: <a href="https://gitlab.haskell.org/ghc/ghc/merge_requests/1973" target="_blank">https://gitlab.haskell.org/ghc/ghc/merge_requests/1973</a></span><br>
<span></span><br>
<span>Compatibility & migration</span><br>
<span>-------------------------</span><br>
<span></span><br>
<span>I drafted a compatibility package `foldable1`
(github[^ref6],</span><br>
<span>haddocks[^ref7]),</span><br>
<span>which I hope could be maintained under <a href="http://github.com/haskell" target="_blank">github.com/haskell</a>
organization.</span><br>
<span>I can act as a maintainer, with a hope that
there won't be a lot</span><br>
<span>of changes happening in `Data.Foldable1`.</span><br>
<span></span><br>
<span>To my surprise, there's already a package with
this name on</span><br>
<span>Hackage[^ref8] by</span><br>
<span>M Farkas-Dyck (cc'd). I hope they would donate
the name to <a href="http://Haskell.org" target="_blank">Haskell.org</a> /</span><br>
<span>CLC;</span><br>
<span>the package won't have any other good use when
`Data.Foldable1` is in</span><br>
<span>`base`,</span><br>
<span>then act as a compat package.</span><br>
<span></span><br>
<span>`Data.Foldable1` contains also instances for
`Lift`, `Backwards` and</span><br>
<span>`Reverse`</span><br>
<span>data types from `transformers`. Perfectly, the
`transformers` bundled</span><br>
<span>with GHC with this change would implement the
instances as well.</span><br>
<span>This change should propage to
`transformers-compat` too.</span><br>
<span></span><br>
<span>Similarly, `containers` would have an instance
for `Tree` (and non-empty</span><br>
<span>`Set` and `Map` when they are added).</span><br>
<span></span><br>
<span>`semigroupoids` would need a bit of work, to
depend on `foldable1`,</span><br>
<span>yet the public changes can be kept quite
minimal.</span><br>
<span>I don't think that anything in reverse
dependencies of `lens` will be</span><br>
<span>broken by</span><br>
<span>this change, if "new" `Foldable1` is re-exported
from `semigroupoids`'</span><br>
<span>`Data.Semigroup.Foldable`[^ref9]</span><br>
<span></span><br>
<span>Other "compat" packages -- like `tagged`,
`bifunctors` -- have to be</span><br>
<span>dealt with</span><br>
<span>case by case. For example whether they should
depend on `foldable1` or</span><br>
<span>other way around.</span><br>
<span></span><br>
<span>[^ref6]: <a href="https://github.com/phadej/foldable1" target="_blank">https://github.com/phadej/foldable1</a></span><br>
<span>[^ref7]: <a href="https://oleg.fi/haddocks/foldable1/" target="_blank">https://oleg.fi/haddocks/foldable1/</a></span><br>
<span>[^ref8]: <a href="https://hackage.haskell.org/package/foldable1" target="_blank">https://hackage.haskell.org/package/foldable1</a></span><br>
<span>[^ref9]:</span><br>
<span><a href="https://hackage.haskell.org/package/semigroupoids-5.3.3/docs/Data-Semigroup-Foldable-Class.html" target="_blank">https://hackage.haskell.org/package/semigroupoids-5.3.3/docs/Data-Semigroup-Foldable-Class.html</a></span><br>
<span></span><br>
<span>Unresolved questions</span><br>
<span>--------------------</span><br>
<span></span><br>
<span>- Should we add `Bifoldable1` too. That should
be trivial.</span><br>
<span>- GHC-8.10 freeze is quite soon, is targeting
GHC-8.12/base-4.15 more</span><br>
<span>realistic?</span><br>
<span></span><br>
<span></span><br>
</div>
</blockquote>
<blockquote type="cite">
<div dir="ltr"><span>_______________________________________________</span><br>
<span>Libraries mailing list</span><br>
<span><a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a></span><br>
<span><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a></span><br>
</div>
</blockquote>
</div>
<span>_______________________________________________</span><br>
<span>Libraries mailing list</span><br>
<span><a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a></span><br>
<span><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a></span><br>
</div>
</blockquote>
</div>
</blockquote>
</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>