GHC: Ticket #3324: Add Foldable and Traversable instances for ((,) a)
http://ghc.haskell.org/trac/ghc/ticket/3324
<p>
These instances are pretty obvious, and no
more or less trivial than the existing instances
for Prelude types. I have found them to be
useful.
</p>
<p>
Since we are touching these modules anyway,
I am attaching two additional minor patches to this
proposal.
</p>
<p>
One is to add a few additional explicit method
implementations in the Foldable and Traversable
instances for Prelude types. These might sometimes
be slightly more efficient, and they better match
the strictness and style of the existing explicit method
implementations.
</p>
<p>
The other is to fix the documentation for the functions
fmapDefault and foldMapDefault in Data.Traversable.
Contrary to what is stated, these cannot be used
as methods in superclasses, since the superclasses
must already exist before these functions can be
defined. Instead, I have paraphrased what
is stated in the documentation above: that the
corresponding superclass methods should be
equivalent to these.
</p>
<p>
Discussion period: two weeks.
</p>
en-usGHChttp://ghc.haskell.org/trac/ghc/chrome/site/ghc_logo.png
http://ghc.haskell.org/trac/ghc/ticket/3324
Trac 1.2.2YitzGaleTue, 23 Jun 2009 11:27:11 GMTattachment set
http://ghc.haskell.org/trac/ghc/ticket/3324
http://ghc.haskell.org/trac/ghc/ticket/3324
<ul>
<li><strong>attachment</strong>
set to <em>tuple_instances.patch</em>
</li>
</ul>
<p>
Add Foldable and Traversable instances for ((,) a)
</p>
TicketYitzGaleTue, 23 Jun 2009 11:28:08 GMTattachment set
http://ghc.haskell.org/trac/ghc/ticket/3324
http://ghc.haskell.org/trac/ghc/ticket/3324
<ul>
<li><strong>attachment</strong>
set to <em>prelude_explicit_methods.patch</em>
</li>
</ul>
<p>
Additional explicit method implementations in the Foldable and Traversable ins tances for Prelude types
</p>
TicketYitzGaleTue, 23 Jun 2009 11:29:02 GMTattachment set
http://ghc.haskell.org/trac/ghc/ticket/3324
http://ghc.haskell.org/trac/ghc/ticket/3324
<ul>
<li><strong>attachment</strong>
set to <em>docs_fmapDefault_foldMapDefault.patch</em>
</li>
</ul>
<p>
Fix documentation for fmapDefault and foldMapDefault
</p>
TicketLouisWassermanTue, 23 Jun 2009 19:06:44 GMT
http://ghc.haskell.org/trac/ghc/ticket/3324#comment:1
http://ghc.haskell.org/trac/ghc/ticket/3324#comment:1
<p>
"The other is to fix the documentation for the functions fmapDefault and foldMapDefault in Data.Traversable. Contrary to what is stated, these cannot be used as methods in superclasses, since the superclasses must already exist before these functions can be defined."
</p>
<p>
I don't think this is correct. Here is a sample usage of fmapDefault in Data.Sequence (which definitely compiles):
</p>
<pre class="wiki">instance Functor ViewL where
fmap = fmapDefault
instance Foldable ViewL where
foldMap = foldMapDefault
instance Traversable ViewL where
traverse _ EmptyL = pure EmptyL
traverse f (x :< xs) = (:<) <$> f x <*> traverse f xs
</pre><p>
This is exactly what I expected from the original documentation.
</p>
<p>
What actually happens is that, in the case of the Functor instance, the Functor instance -- specifically, fmapDefault -- is defined in terms of the Traversable instance, and the Traversable instance depends on the Functor instance. This sets up a legal recursion.
</p>
<p>
The following, in contrast, would not be legal:
</p>
<pre class="wiki">data Foo a b = ...
instance Traversable (Foo a) => Functor (Foo a) where
fmap = fmapDefault
instance Traversable (Foo a) where
...
</pre><p>
This would have set up a loop of dependencies, but in the first example, the key is that the presence of the Functor instance (combined with the Traversable instance) implies that fmapDefault is defined, and is therefore legal.
</p>
<p>
I hope I'm making sense, but as I read it, the original documentation was correct.
</p>
TicketYitzGaleThu, 25 Jun 2009 08:00:55 GMT
http://ghc.haskell.org/trac/ghc/ticket/3324#comment:2
http://ghc.haskell.org/trac/ghc/ticket/3324#comment:2
<p>
As noted by Ross Paterson on the libraries list: yes, you are correct,
I was wrong. Except that it should be noted that using fmapDefault will only
work if an explicit implementation was provided for traverse,
otherwise infinite recursion will result.
</p>
<p>
The thread is here: <a class="ext-link" href="http://www.haskell.org/pipermail/libraries/2009-June/011991.html"><span class="icon"></span>http://www.haskell.org/pipermail/libraries/2009-June/011991.html</a>
</p>
<p>
I will paste below my next attempt that I posted to the list
in reply to Ross. The ideas are:
</p>
<ul><li>to note the requirement of a traverse implementation
</li><li>to make explicit what we mean by using these functions to create Functor and Foldable instances
</li><li>to note more clearly the other use of the two default functions: to test the consistency of a Traversable instance against the
</li></ul><p>
Foldable and Functor instances.
</p>
<p>
Of course another option would be to keep it simple -
keep the original, with just an added note about the
requirement of an explicit traverse.
</p>
<p>
Here's the new proposal that I wrote
in my reply to Ross:
</p>
<p>
In the documentation for class Traversable, change
(<code>fmapDefault</code>) to (see <code>fmapDefault</code>), similarly
for foldMapDefault.
</p>
<p>
Documentation for fmapDefault:
</p>
<pre class="wiki">-- | This function should be equivalent to `fmap` in
-- the `Functor` superclass instance. If you do not
-- already have a `Functor` instance, you can use
-- this function to define one:
--
-- > instance Functor T where
-- > fmap = fmapDefault
--
-- Note, however, that this will lead to infinite
-- recursion if you did not provide an explicit
-- implementation of the `traverse` method.
</pre><p>
Documentation for foldMapDefault:
</p>
<pre class="wiki">-- This function should be equivalent to `foldMap` in
-- the `Foldable` superclass instance. If you do not
-- already have a `Foldable` instance, you
-- can use this function to define one:
--
-- > instance Foldable T where
-- > foldMap = foldMapDefault
</pre>
TicketiglooSun, 12 Jul 2009 21:22:34 GMTdifficulty, milestone set
http://ghc.haskell.org/trac/ghc/ticket/3324#comment:3
http://ghc.haskell.org/trac/ghc/ticket/3324#comment:3
<ul>
<li><strong>difficulty</strong>
set to <em>Unknown</em>
</li>
<li><strong>milestone</strong>
set to <em>Not GHC</em>
</li>
</ul>
TicketiglooSun, 20 Jun 2010 13:11:04 GMTstatus changed; failure, resolution set
http://ghc.haskell.org/trac/ghc/ticket/3324#comment:4
http://ghc.haskell.org/trac/ghc/ticket/3324#comment:4
<ul>
<li><strong>status</strong>
changed from <em>new</em> to <em>closed</em>
</li>
<li><strong>failure</strong>
set to <em>None/Unknown</em>
</li>
<li><strong>resolution</strong>
set to <em>wontfix</em>
</li>
</ul>
<p>
Looks like an abandoned proposal. If that's not the case, please re-open and give a discussion summary and consensus decision, as described on the <a class="ext-link" href="http://www.haskell.org/haskellwiki/Library_submissions"><span class="icon"></span>process page</a>.
</p>
Ticket