Send Beginners mailing list submissions to
        beginners@haskell.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://www.haskell.org/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.  Good style on "." and "$" pipeline? (Carlos J. G. Duarte)
   2. Re:  Good style on "." and "$" pipeline? (Darren Grant)
   3. Re:  Good style on "." and "$" pipeline? (Brent Yorgey)
   4. Re:  Good style on "." and "$" pipeline? (koomi)
   5. Re:  Good style on "." and "$" pipeline? (Felipe Almeida Lessa)
   6.  The Holy Trinity of Functional Programming (Costello, Roger L.)
   7. Re:  Good style on "." and "$" pipeline? (Ozgur Akgun)


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

Message: 1
Date: Tue, 21 Aug 2012 21:34:49 +0100
From: "Carlos J. G. Duarte" <carlos.j.g.dua...@gmail.com>
Subject: [Haskell-beginners] Good style on "." and "$" pipeline?
To: beginners@haskell.org
Message-ID: <5033f0e9.1040...@gmail.com>
Content-Type: text/plain; charset="us-ascii"

An HTML attachment was scrubbed...
URL: 
<http://www.haskell.org/pipermail/beginners/attachments/20120821/a699e877/attachment-0001.htm>

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

Message: 2
Date: Tue, 21 Aug 2012 13:43:37 -0700
From: Darren Grant <therealklu...@gmail.com>
Subject: Re: [Haskell-beginners] Good style on "." and "$" pipeline?
To: "Carlos J. G. Duarte" <carlos.j.g.dua...@gmail.com>
Cc: beginners@haskell.org
Message-ID:
        <ca+jd6sihau_pkxw5zyh1xtj848ejkwrsw8wabjoxnuhzcwo...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1

I am very new to Haskell, but what I've discovered so far is that the
application operator $ is used to improve code readability. It can
sometimes be used eliminate the need for parentheses that break
natural left-to-right reading.

Hoogle covers an example:
http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:-36-


Cheers!



On Tue, Aug 21, 2012 at 1:34 PM, Carlos J. G. Duarte
<carlos.j.g.dua...@gmail.com> wrote:
> Hi. Often I see the following pattern to build function "pipelines":
>
> x = f1 . f2 $ fn arg
>
> They use the "$" just before the last function call. I never got much into
> it: when to use the "." or the "$"? I think today I figured it out:
> => "." is a function composition operator: used to "merge" functions;
> => "$" is a function application operator: used to apply a function to its
> arguments.
>
> If this reasoning is correct, I think the following should be a more
> adequate pattern:
>
> x = f1 . f2 . fn $ arg
>
> To merge/compose all functions first and apply the composed function to its
> parameter(s).
> Am I correct on this? Thx
>
>
> _______________________________________________
> Beginners mailing list
> Beginners@haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>



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

Message: 3
Date: Tue, 21 Aug 2012 16:43:53 -0400
From: Brent Yorgey <byor...@seas.upenn.edu>
Subject: Re: [Haskell-beginners] Good style on "." and "$" pipeline?
To: beginners@haskell.org
Message-ID: <20120821204353.ga22...@seas.upenn.edu>
Content-Type: text/plain; charset=us-ascii

On Tue, Aug 21, 2012 at 09:34:49PM +0100, Carlos J. G. Duarte wrote:
>    Hi. Often I see the following pattern to build function "pipelines":
> 
>      x = f1 . f2 $ fn arg
> 
>    They use the "$" just before the last function call. I never got much into
>    it: when to use the "." or the "$"? I think today I figured it out:
>    => "." is a function composition operator: used to "merge" functions;
>    => "$" is a function application operator: used to apply a function to its
>    arguments.
> 
>    If this reasoning is correct, I think the following should be a more
>    adequate pattern:
> 
>      x = f1 . f2 . fn $ arg
> 
>    To merge/compose all functions first and apply the composed function to
>    its parameter(s). 
>    Am I correct on this? Thx

Yes, you are absolutely correct.  But sometimes people do something
like

  f1 . f2 $ fn arg

if for some reason they are thinking of "fn arg" as a "primitive"
starting point, and then applying a pipeline of functions f2, f1 to
that.  But it is really just a different point of view.  In any case,
both (f1 . f2 . fn $ arg) and (f1 . f2 $ fn arg) are perfectly good
style.  Having more than one $, like (f1 $ f2 $ fn $ arg), is frowned
upon.

-Brent



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

Message: 4
Date: Wed, 22 Aug 2012 03:34:33 +0200
From: koomi <ko...@hackerspace-bamberg.de>
Subject: Re: [Haskell-beginners] Good style on "." and "$" pipeline?
To: beginners@haskell.org
Message-ID: <50343729.1080...@hackerspace-bamberg.de>
Content-Type: text/plain; charset=ISO-8859-1

On 21.08.2012 22:43, Brent Yorgey wrote:
> Having more than one $, like (f1 $ f2 $ fn $ arg), is frowned upon.
Care to explain why this is considered bad? I don't see anything wrong
with this.

koomi




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

Message: 5
Date: Tue, 21 Aug 2012 22:41:17 -0300
From: Felipe Almeida Lessa <felipe.le...@gmail.com>
Subject: Re: [Haskell-beginners] Good style on "." and "$" pipeline?
To: koomi <ko...@hackerspace-bamberg.de>
Cc: beginners@haskell.org
Message-ID:
        <CANd=ogehwojgktz_zzlfgmfypdreua6kner0settti7fxeo...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 21, 2012 at 10:34 PM, koomi <ko...@hackerspace-bamberg.de> wrote:
> On 21.08.2012 22:43, Brent Yorgey wrote:
>> Having more than one $, like (f1 $ f2 $ fn $ arg), is frowned upon.
> Care to explain why this is considered bad? I don't see anything wrong
> with this.

It's just a matter of taste.  Personally, I usually prefer using many
($)s rather than combining (.)s and ($)s on the same "phrase".  For
example, I prefer

  foo =
    finish $
    doSomethingOther $
    doSomething $
    initialArg

to

  foo =
    finish .
    doSomethingOther .
    doSomething $
    initialArg

It gives me a feel of simmetry.  You may even align the $s, either on
the left or on the right.

But, like I said, it's just a matter of taste =).

Cheers,

-- 
Felipe.



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

Message: 6
Date: Wed, 22 Aug 2012 09:27:08 +0000
From: "Costello, Roger L." <coste...@mitre.org>
Subject: [Haskell-beginners] The Holy Trinity of Functional
        Programming
To: "beginners@haskell.org" <beginners@haskell.org>
Message-ID:
        <b5fee00b53cf054aa8439027e8fe17751e62f...@imcmbx04.mitre.org>
Content-Type: text/plain; charset="us-ascii"

Hi Folks,

In Richard Bird's book (Introduction to Functional Programming using Haskell) 
he has a fascinating discussion on three key aspects of functional programming. 
Below is my summary of his discussion.  /Roger

---------------------------------------------------------
The Holy Trinity of Functional Programming
---------------------------------------------------------
These three ideas constitute the holy trinity of functional programming:

1.  User-defined recursive data types.
2.  Recursively defined functions over recursive data types.
3.  Proof by induction: show that some property P(n) holds for each element of 
a recursive data type.

Here is an example of a user-defined recursive data type. It is a declaration 
for the natural numbers 0, 1, 2, ...:

        data Nat = Zero | Succ Nat

The elements of this data type include:

        Zero,  Succ Zero,  Succ (Succ Zero),  Succ (Succ (Succ Zero)),  ...

To understand this, when creating a Nat value we have a choice of either Zero 
or Succ Nat. Suppose we choose Succ Nat. Well, now we must choose a value for 
the Nat in Succ Nat. Again, we have a choice of either Zero or Succ Nat. 
Suppose this time we choose Zero, to obtain Succ Zero.

The ordering of the elements in the Nat data type can be specified by defining 
Nat to be a member of the Ord class:

        instance Ord Nat where
                      Zero < Zero               =  False
                      Zero < Succ n     =  True
                      Succ m < Zero     =  False
                      Succ m < Succ n   =  (m < n)

Here is how the Nat version of the expression 2 < 3 is evaluated:

           Succ (Succ Zero) < Succ (Succ (Succ Zero))   -- Nat version of 2 < 3

        = Succ Zero < Succ (Succ Zero)                  -- by the 4th equation 
defining order

        = Zero < Succ Zero                              -- by the 4th equation 
defining order

        = True                                          -- by the 2nd equation 
defining order

Here is a recursively defined function over the data type; it adds two Nat 
elements:

        (+) :: Nat -> Nat -> Nat
        m + Zero = m
        m + Succ n = Succ(m + n)

Here is how the Nat version of 0 + 1 is evaluated:

           Zero + Succ Zero                             -- Nat version of 0 + 1

        = Succ (Zero + Zero)                            -- by the 2nd equation 
defining +

        = Succ Zero                                     -- by the 1st equation 
defining +

Here is another recursively defined function over the data type; it subtracts 
two Nat elements:

        (-) :: Nat -> Nat -> Nat
        m - Zero = m
        Succ m - Succ n = m - n

If the Nat version of 0 - 1 is executed, then the result is undefined:

        Zero - Succ Zero

The "undefined value" is denoted by this symbol: _|_ (also known as "bottom")

Important: _|_ is an element of *every* data type.

So we must expand the list of elements in Nat:

        _|_,  Zero,  Succ Zero,  Succ (Succ Zero),  Succ (Succ (Succ Zero)),  
...

There are still more elements of Nat. Suppose we define a function that returns 
a Nat. Let's call the function undefined:

        undefined :: Nat
        undefined = undefined

It is an infinitely recursive function: when invoked it never stops until the 
program is interrupted.

This function undefined is denoted by the symbol _|_

Recall how we defined the ordering of values in Nat:

        instance Ord Nat where
              Zero < Zero               =  False
              Zero < Succ n     =  True
              Succ m < Zero     =  False
              Succ m < Succ n   =  (m < n)

>From that ordering we can see that Succ _|_ is an element of Nat:

           Zero < Succ undefined                                -- Note: same 
as Zero < Succ _|_

        = True                                          -- by the 2nd equation 
defining order

And Succ (Succ _|_ ) is an element of Nat:

           Succ Zero < Succ (Succ undefined)            -- Note: same as Zero < 
Succ (Succ _|_ )

        = Zero < Succ undefined                         -- by the 4th equation 
defining order

        = True                                          -- by the 2nd equation 
defining order

And Succ (Succ (Succ _|_ ) is an element of Nat, and so forth.

So the list of elements in Nat expands:

..., Succ (Succ (Succ _|_ )),  Succ (Succ _|_ ),  Succ _|_, _|_,  Zero,  Succ 
Zero,  Succ (Succ Zero),  Succ (Succ (Succ Zero)), ...

One can interpret the extra values in the following way: 

_|_ corresponds to the natural number about which there is absolutely no 
information

Succ _|_ to the natural number about which the only information is that it is 
greater than Zero

Succ (Succ _|_ ) to the natural number about which the only information is that 
it is greater than Succ Zero

And so on

There is one further value of Nat, namely the "infinite" number:

        Succ (Succ (Succ (Succ ...)))

It can be defined by this function:

        infinity :: Nat
        infinity = Succ infinity

It is different from all the other Nat values because it is the only number for 
which Succ m < infinity for all finite numbers m: 

        Zero < infinity
        = True

        Succ Zero < infinity
        = True

        Succ (Succ Zero) < infinity
        = True

Thus, the values of Nat can be divided into three classes:

-  The finite values, Zero,  Succ Zero,  Succ (Succ Zero), and so on.
-  The partial values, _|_,  Succ _|_,  Succ (Succ _|_ ), and so on.
-  The infinite value.

Important: the values of *every* recursive data type can be divided into three 
classes:

-  The finite values of the data type.
-  The partial values, _|_, and so on.
-  The infinite values.

Although the infinite Nat value is not of much use, the same is not true of the 
infinite values of other data types.

Recap: We have discussed two aspects of the holy trinity of functional 
programming: recursive data types and recursively defined functions over those 
data types. The third aspect is induction, which is discussed now.

Induction allows us to reason about the properties of recursively defined 
functions over a recursive data type. 

In the case of Nat the principle of induction can be stated as follows: in 
order to show that some property P(n) holds for each finite number n of Nat, it 
is sufficient to treat two cases:

        Case (Zero). Show that P(Zero) holds.

        Case (Succ n). Show that if P(n) holds, then P(Succ n) also holds.

As an example, let us prove this property (the identity for addition):

        Zero + n = n

Before proving this, recall that + is defined by these two equations:

        m + Zero = m
        m + Succ n = Succ(m + n)

Proof: The proof is by induction on n. 

Case (Zero). Substitute Zero for n in the equation Zero + n = n. So we have to 
show that Zero + Zero = Zero, which is immediate from the first equation 
defining +.

Case (Succ n). Assume P(n) holds; that is, assume Zero + n = n holds. This 
equation is referred to as the induction hypothesis. We have to show that 
P(Succ n) holds; that is, show that Zero + Succ n = Succ n holds. We do so by 
simplifying the left-hand expression:

           Zero + Succ n

        = Succ (Zero + n)                       -- by the 2nd equation defining 
+

        = Succ (n)                              -- by the induction hypothesis

We have proven the two cases and so we have proven that Zero + n = n holds for 
all finite numbers of Nat.

Full Induction. To prove that a property P holds not only for finite members of 
Nat, but also for every partial (undefined) number, then we have to prove three 
things:

        Case ( _|_ ). Show that P( _|_ ) holds.

        Case (Zero). Show that P(Zero) holds.

        Case (Succ n). Show that if P(n) holds, then P(Succ n) holds also.

To just prove that a property P holds for every partial (undefined) number, 
then we omit the second case.

To illustrate proving a property that holds for every partial number (not for 
the finite numbers), let us prove the rather counterintuitive result that m + n 
= n for all numbers m and all partial numbers n.

For easy reference, we repeat the definition of +

        m + Zero = m
        m + Succ n = Succ(m + n)

Proof: The proof is by partial number induction on n.

Case ( _|_ ). Substitute _|_ for n in the equation m + n = n. So we have to 
show that m + _|_ = _|_, which is true since _|_ does not match either of the 
patterns in the definition of +.

Case (Succ n). We assume P(n) holds; that is, assume m + n = n holds. This 
equation is the induction hypothesis. We have to show that P(Succ n) holds; 
that is, show that m + Succ n = Succ n holds. For the left-hand side we reason

           m + Succ n

        = Succ(m + n)                           -- by the second equation for +

        = Succ(n)                               -- by the induction hypothesis

Since the right-hand side is also Succ n, we are done.

The omitted case (m + Zero = Zero) is false, which is why the property does not 
hold for finite numbers.

As an added bonus, having proved that an equation holds for all partial 
(undefined) numbers, we can assert that it holds for the infinite number too; 
that is, P(infinity) holds. Thus, we can now assert that m + infinity = 
infinity for all numbers m.



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

Message: 7
Date: Wed, 22 Aug 2012 10:32:25 +0100
From: Ozgur Akgun <ozgurak...@gmail.com>
Subject: Re: [Haskell-beginners] Good style on "." and "$" pipeline?
To: Felipe Almeida Lessa <felipe.le...@gmail.com>
Cc: beginners@haskell.org
Message-ID:
        <CALzazPCfTH6rk3MUMXFi-V_a=ZfCKuKeB_OU+dS=xmr4qgg...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

Hi,

On 22 August 2012 02:41, Felipe Almeida Lessa <felipe.le...@gmail.com>wrote:

> But, like I said, it's just a matter of taste =).
>

If we are down to matters of taste, this is how I like to do it:

doFoo = finish . doSomethingOther . doSomething
foo = doFoo initialArg

Ozgur
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://www.haskell.org/pipermail/beginners/attachments/20120822/2811ddf9/attachment.htm>

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

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 50, Issue 23
*****************************************

Reply via email to