Proposal: Add missing Foldable/Traversable instances for Prelude types

I'd like to propose adding the following missing instances to Data.Foldable and Data.Traversable respectively, since there isn't a canonical location that they could be added outside of those packages without orphans, their definition is unambiguous, and they are quite useful (plus, I happen to need them for a monad transformer in my adjunctions package). instance Foldable (Either a) where foldMap f (Left a) = mempty foldMap f (Right b) = f b instance Foldable ((,)e) where foldMap f ea = f (snd ea) instance Traversable (Either a) where traverse f (Left a) = pure (Left a) traverse f (Right a) = Right <$> f a instance Traversable ((,)e) where traverse f ~(e,a) = (,) e <$> f a Discussion period: 2 weeks -Edward Kmett

On 21 Jan 2011, at 23:33, Edward Kmett wrote:
I'd like to propose adding the following missing instances to Data.Foldable and Data.Traversable respectively, since there isn't a canonical location that they could be added outside of those packages without orphans, their definition is unambiguous, and they are quite useful (plus, I happen to need them for a monad transformer in my adjunctions package).
instance Foldable (Either a) where foldMap f (Left a) = mempty foldMap f (Right b) = f b
instance Foldable ((,)e) where foldMap f ea = f (snd ea)
instance Traversable (Either a) where traverse f (Left a) = pure (Left a) traverse f (Right a) = Right <$> f a
instance Traversable ((,)e) where traverse f ~(e,a) = (,) e <$> f a
Discussion period: 2 weeks
+1 Conor

On 01/21/11 18:33, Edward Kmett wrote:
I'd like to propose adding the following missing instances to Data.Foldable and Data.Traversable respectively, since there isn't a canonical location that they could be added outside of those packages without orphans, their definition is unambiguous, and they are quite useful (plus, I happen to need them for a monad transformer in my adjunctions package).
instance Foldable (Either a) where foldMap f (Left a) = mempty foldMap f (Right b) = f b
instance Foldable ((,)e) where foldMap f ea = f (snd ea)
instance Traversable (Either a) where traverse f (Left a) = pure (Left a) traverse f (Right a) = Right<$> f a
instance Traversable ((,)e) where traverse f ~(e,a) = (,) e<$> f a
Those look correct. Is there some reason you chose to make the (,) instances less strict in the pair? For example, traverse on "undefined" gives you, modulo the applicative layer, "(undefined, f undefined)". (I haven't thought of a reason (practical or theoretical) for either behavior.) -Isaac

I went with the default being to avoid prematurely forcing a bottom when possible, to avoid being called out by the strictness police, but I'm not terribly wedded to the behavior. -Edward On Fri, Jan 21, 2011 at 7:27 PM, Isaac Dupree < ml@isaac.cedarswampstudios.org> wrote:
On 01/21/11 18:33, Edward Kmett wrote:
I'd like to propose adding the following missing instances to Data.Foldable and Data.Traversable respectively, since there isn't a canonical location that they could be added outside of those packages without orphans, their definition is unambiguous, and they are quite useful (plus, I happen to need them for a monad transformer in my adjunctions package).
instance Foldable (Either a) where foldMap f (Left a) = mempty foldMap f (Right b) = f b
instance Foldable ((,)e) where foldMap f ea = f (snd ea)
instance Traversable (Either a) where traverse f (Left a) = pure (Left a) traverse f (Right a) = Right<$> f a
instance Traversable ((,)e) where traverse f ~(e,a) = (,) e<$> f a
Those look correct. Is there some reason you chose to make the (,) instances less strict in the pair? For example, traverse on "undefined" gives you, modulo the applicative layer, "(undefined, f undefined)". (I haven't thought of a reason (practical or theoretical) for either behavior.)
-Isaac
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

+1
On 22 January 2011 05:16, Edward Kmett
I went with the default being to avoid prematurely forcing a bottom when possible, to avoid being called out by the strictness police, but I'm not terribly wedded to the behavior.
Just for reference, the Functor instance on pairs is strict in the pair: instance Functor ((,) a) where fmap f (x,y) = (x, f y) Bas

On Sat, Jan 22, 2011 at 05:12:00PM +0100, Bas van Dijk wrote:
On 22 January 2011 05:16, Edward Kmett
wrote: I went with the default being to avoid prematurely forcing a bottom when possible, to avoid being called out by the strictness police, but I'm not terribly wedded to the behavior.
Just for reference, the Functor instance on pairs is strict in the pair:
instance Functor ((,) a) where fmap f (x,y) = (x, f y)
And this is necessary for the functor laws, because with fmap' f ~(x,y) = (x, f y) we obtain: fmap' id undefined = (undefined, undefined) /= undefined = id undefined Wolfram

On Sat, 22 Jan 2011, kahl@cas.mcmaster.ca wrote:
On Sat, Jan 22, 2011 at 05:12:00PM +0100, Bas van Dijk wrote:
Just for reference, the Functor instance on pairs is strict in the pair:
instance Functor ((,) a) where fmap f (x,y) = (x, f y)
And this is necessary for the functor laws, because with
fmap' f ~(x,y) = (x, f y)
we obtain:
fmap' id undefined = (undefined, undefined) /= undefined = id undefined
Thank you lot! I already wondered for similar data structures how to define fmap the correct way. But then I see, that transformers:WriterT.Lazy matches lazily, too: http://hackage.haskell.org/packages/archive/transformers/0.2.2.0/doc/html/sr...

On Fri, Jan 21, 2011 at 11:16:46PM -0500, Edward Kmett wrote:
I went with the default being to avoid prematurely forcing a bottom when possible, to avoid being called out by the strictness police, but I'm not terribly wedded to the behavior.
There are two opposing police forces out there. I'd prefer the strict versions: foldMap f (e,a) = f a traverse f (e,a) = (,) e <$> f a to match the fmap definition.

Thats fine by me. I prefer this version as well. I just want there to be
_an_ instance.
On Thu, Jan 27, 2011 at 6:00 AM, Ross Paterson
On Fri, Jan 21, 2011 at 11:16:46PM -0500, Edward Kmett wrote:
I went with the default being to avoid prematurely forcing a bottom when possible, to avoid being called out by the strictness police, but I'm not terribly wedded to the behavior.
There are two opposing police forces out there. I'd prefer the strict versions:
foldMap f (e,a) = f a traverse f (e,a) = (,) e <$> f a
to match the fmap definition.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

On Fri, Jan 21, 2011 at 06:33:10PM -0500, Edward Kmett wrote:
I'd like to propose adding the following missing instances to Data.Foldable and Data.Traversable respectively, since there isn't a canonical location that they could be added outside of those packages without orphans, their definition is unambiguous, and they are quite useful (plus, I happen to need them for a monad transformer in my adjunctions package).
instance Foldable (Either a) where foldMap f (Left a) = mempty foldMap f (Right b) = f b
instance Foldable ((,)e) where foldMap f ea = f (snd ea)
instance Traversable (Either a) where traverse f (Left a) = pure (Left a) traverse f (Right a) = Right <$> f a
instance Traversable ((,)e) where traverse f ~(e,a) = (,) e <$> f a
+1 -Brent
participants (8)
-
Bas van Dijk
-
Brent Yorgey
-
Conor McBride
-
Edward Kmett
-
Henning Thielemann
-
Isaac Dupree
-
kahl@cas.mcmaster.ca
-
Ross Paterson