Send Beginners mailing list submissions to
        beginners@haskell.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        beginners-requ...@haskell.org

You can reach the person managing the list at
        beginners-ow...@haskell.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1. Re:  to avoid naming intermediate variables (Michael Orlitzky)
   2. Re:  to avoid naming intermediate variables (Dennis Raddle)


----------------------------------------------------------------------

Message: 1
Date: Mon, 22 Feb 2016 10:17:48 -0500
From: Michael Orlitzky <mich...@orlitzky.com>
To: beginners@haskell.org
Subject: Re: [Haskell-beginners] to avoid naming intermediate
        variables
Message-ID: <56cb269c.7090...@orlitzky.com>
Content-Type: text/plain; charset=utf-8

On 02/22/2016 03:40 AM, Dennis Raddle wrote:
> 
> ...So I had to write something like this.
> 
> compute :: [Int] -> [Int] -> [Int] -> [(Int,Int)]
> 
> func :: [Int] -> [(Int,Int)]
> func xs = compute xs (filter isSmall xs) (filter isLarge xs)
> 
> 
> but I could also write
> 
> compute :: ([Int],([Int],[Int])) -> [(Int,Int)]
> 
> func = compute . (id &&& filter isSmall &&& filter isLarge)
> 
> So I had to change the inputs to 'compute' into this kind of awkward
> tuple form, but I eliminated four 'xs', plus eliminated the need to come
> up with the name 'xs'. 
> 
> Can I get a comment on whether this makes sense as way to do things?
> 

It's pushing it. Once you've seen the trick with (&&&) it's tempting to
use it. When I see (id &&& f &&& g), in my head I get a picture of some
argument coming in and being split along three wires that get fed into
id, f, and g simultaneously. The output from those three black-boxes
then get fed into compute:

             ----f----
            /         \
  compute <------g------<-- xs
            \         /
             ----id---

So while details with the nested tuple are ugly, what will happen is
pretty clear to me. But how long did you have to play with the arrow
combinators to make this work? If you-two-weeks-ago were to see that line,

  compute :: ([Int],([Int],[Int])) -> [(Int,Int)]
  func = compute . (id &&& filter isSmall &&& filter isLarge)

how long would it have taken you to figure out what it did?

How does it impact your documentation for the "compute" function? I
imagine it was something like "takes a list of Ints, the small half of
that list, and the large half of that list, and then computes something
cool." Now it will be "takes a pair whose first component is a list of
Ints, and the second component is a pair whose first component is a list
of the small half of the list in the first component of the big pair,
and..." It's hard to explain because it's weird to think about.

In this case, the second and third arguments to compute can be...
computed... from the first, so in practice I would do something like,

  compute_stuff :: [Int] -> [(Int,Int)]
  compute_stuff xs =
    compute xs small_xs big_xs
    where
      small_xs = filter isSmall xs
      big_xs = filter isLarge xs

      compute :: [Int] -> [Int] -> [Int] -> [(Int,Int)]
      compute = -- whatever it's supposed to do

(Unrelated: it might make more sense to loop through "xs" once and
return a pair of the small/large elements. That way you don't have to
make two passes. Depends on the size of the list.)

If you're just code golfing, you don't need to change the signature of
the compute function. Hitting it with "uncurry" once makes it take a
tuple, and hitting it with (uncurry . uncurry) makes it take a tuple
whose first component is a tuple:

  -- oh god what have i done
  func :: [Int] -> [(Int, Int)]
  func = ((uncurry . uncurry) compute .
           ((id &&& filter isSmall) &&& filter isLarge))



------------------------------

Message: 2
Date: Mon, 22 Feb 2016 07:35:33 -0800
From: Dennis Raddle <dennis.rad...@gmail.com>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <beginners@haskell.org>
Subject: Re: [Haskell-beginners] to avoid naming intermediate
        variables
Message-ID:
        <cakxlvooldycfztyn-u0u1p-tbrxrbhg9borh77yzujhsvz3...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

Yeah, maybe I've been a little too enthusiastic about code golfing. I've
noticed that haskell programs usually have short functions (compared to
imperative languages). I love this---I love how when you get a function
down to four or fewer lines, you can tell its structure in a glance. Yes,
some Haskell structures can look confusing at first, but I find that with
practice looking at them, they start to look natural. Like the way that
your mind pictures &&& splitting the input---I'm sure you find that doesn't
take any effort and feels like a common and natural pattern. It seems to
work like that with much of Haskell.

Oh, can I bring up one other intermediate variable elimination situation?

I used to do things like

func :: IO MyData
func = do
  x <- readMyData
  return $ someProcessing x

When I first encountered Monads, I was confused by functions that move
things into Monads, like 'liftM'. But I am starting to see the light. I
realized I could do

func = someProcessing `liftM` readMyData

Or

func = readMyData >>= someProcessing

I was explaining to a friend that Haskell's abstracted patterns seem
confusing to me, coming from an imperative background. She only has a
little experience programming, so I tried giving some analogies. Say you
are an imperative programmer and you are do a physical simulation of
automobiles. You see that they all have an engine, so you write some code
that handles abstracted common features of engines.

In Haskell, abstracted patterns are more like this--say you have a a
forklift that manipulates boxes. say that's your "function." Then you write
a function that produces a forklift that manipulates boxes that are inside
trucks. In the imperative world, it's like "huh? where does that get you?"
But it makes more sense now.

D
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20160222/06a84d8b/attachment-0001.html>

------------------------------

Subject: Digest Footer

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


------------------------------

End of Beginners Digest, Vol 92, Issue 27
*****************************************

Reply via email to