[Haskell-cafe] Foldable for (,)

Chris Smith cdsmith at gmail.com
Wed May 3 09:32:18 UTC 2017


So, suppose I have a function:

    f :: a -> IO b

and I need a function of the related type:

    (SideValue, a) -> IO (SideValue, b)

Here, SideValue is some kind of state that I am manually threading through
a bunch of computations.  For instance, maybe I'm counting steps in a
computation, and SideValue = Int.  Whatever.  In the particular case of
`f`, I don't actually want to use it at all, because maybe `f` doesn't have
any steps that need to be counted.  But in general, maybe I'll be combining
`f` with a bunch of other computations that *do* count steps.  Maybe I have
a list of such functions, and I want to add `f` into that list.  Before I
can do that, I need to get `f` into the right form, so I can compose it
cleanly with everything else.

I could use a combination of pattern matching and fmap, like this (using
the TupleSections extension for convenience):

    \ (s, x) -> fmap (s,) (f x)

But it's just a little cleaner to write this instead:

    traverse f

Does that make sense?

On Wed, May 3, 2017 at 2:12 AM, Jonathon Delgado <voldermort at hotmail.com>
wrote:

> Why do you want to traverse a tuple instead of fmap? i.e. what can you do
> with Foldable/Traversable for (,) that you can't do with Functor?
>
> My background, as you can probably guess, is beginner.
>
>
> From: Haskell-Cafe <haskell-cafe-bounces at haskell.org> on behalf of Chris
> Smith <cdsmith at gmail.com>
> Sent: 03 May 2017 08:51
> To: Tony Morris
> Cc: haskell-cafe at haskell.org
> Subject: Re: [Haskell-cafe] Foldable for (,)
>
>
> Replying to myself, I suppose one good answer is that whether or not you
> care about Foldable instances for tuples, you might care about Traversable
> instances, and those require Foldable as a superclass.
>
>
> For example, one possible specialization of `traverse` is:
>
>
>     traverse :: (a -> IO b) -> (SideValue, a) -> IO (SideValue, b)
>
>
> Jonathon, I don't know how much background you're coming from, so I'd be
> happy to explain that in more detail if you need it.
>
>
> On Wed, May 3, 2017 at 1:44 AM, Chris Smith  <cdsmith at gmail.com> wrote:
>
> I'm also interested in Jonathon's question, so let me try to bring things
> back to the question.  Everyone agrees that there's only one reasonable way
> to define this instance if it exists.  But the question is: why is it
> defined at all?
>
>
> That's an easy question to answer for Functor, Applicative, and Monad.
> But I am having trouble giving a simple or accessible answer for Foldable.
> Do you know one?
>
>
>
>
> On Wed, May 3, 2017 at 1:32 AM, Tony Morris  <tonymorris at gmail.com> wrote:
>  It's Foldable for ((,) a).
>
> It is not Foldable for any of these things:
>
> * (,)
> * tuples
> * pairs
>
> In fact, to talk about a Foldable for (,) or "tuples" is itself a kind
> error. There is no good English name for the type constructor ((,) a)
> which I suspect, along with being unfamiliar with utilising the
> practical purpose of types (and types of types) is the root cause of all
> the confusion in this discussion.
>
> Ask yourself what the length of this value is:
>
> [[1,2,3], [4,5,6]]
>
> Is it 6? What about this one:
>
> [(1, 'a'), (undefined, 77)]
>
> Is it 4? No, obviously not, which we can determine by:
>
> :kind Foldable :: (* -> *) -> Constraint
> :kind [] :: * -> *
>
> Therefore, there is no possible way that the Foldable instance for []
> can inspect the elements (and determine that they are pairs in this
> case). By this method, we conclude that the length of the value is 2. It
> cannot be anything else, some assumptions about length itself put aside.
>
> By this ubiquitous and very practical method of reasoning, the length of
> any ((,) a) is not only one, but very obviously so.
>
>
>
> On 03/05/17 17:21, Jonathon Delgado wrote:
> > I sent the following post to the Beginners list a couple of weeks ago
> (which failed to furnish an actual concrete example that answered the
> question). Upon request I'm reposting it to Café:
> >
> > I've seen many threads, including the one going on now, about why we
> need to have:
> >
> > length (2,3) = 1
> > product (2,3) = 3
> > sum (2,3) = 3
> > or (True,False) = False
> >
> > but the justifications all go over my head. Is there a beginner-friendly
> explanation for why such seemingly unintuitive operations should be allowed
> by default?
> > _______________________________________________
> > Haskell-Cafe mailing list
> > To (un)subscribe, modify options or view archives go to:
> >  http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > Only members subscribed via the mailman list are allowed to post.
>
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
>
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20170503/cc84d68d/attachment-0001.html>


More information about the Haskell-Cafe mailing list