OOP exercise with closures

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

OOP exercise with closures

Lawrence Bottorff-2
First, thanks for all the help you've offered. Often enough, it's so much that it takes me time to sift through all the good stuff. Thanks again.

Okay, I'm in Lesson 10 of Get Programming with Haskell  and we're creating an OOP-like world with closures. The first step is a cup object with one attribute, its ounce size. Here's a "constructor"

cup :: t1 -> (t1 -> t2) -> t2
cup flOz = \message -> message flOz

so this returns upon use

> myCup = cup 6

myCup which has "internally" a lambda function

(\message -> message) 6

waiting, correct?

Now a "method"

getOz aCup = aCup (\foz -> foz)

creates a closure on the lambda function (\foz -> foz) . So upon calling

> getOz myCup
6

I'm guessing myCup (\foz -> foz) was evaluated, but I don't understand how the 6 that went in as the bound variable in the constructor came out again with getOz. As I understand it, the cup constructor creates a closure around the given bound argument flOz -- which is confusing because I thought closures "carried" free variables, not bound variables. Perhaps the getOz lambda function (\foz -> foz) replaces completely the (\message -> message) lambda function? So the constructor could have been written

cup flOz =  (\message -> message) flOz

In any case I'm shaky on how A) cup 6 sets up/stores the 6 in the creation of myCup and then how getOz pops it out again.

LB






_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: OOP exercise with closures

Francesco Ariis
Il 29 dicembre 2020 alle 15:43 Lawrence Bottorff ha scritto:

> Okay, I'm in Lesson 10 of *Get Programming with Haskell * and we're
> creating an OOP-like world with closures. The first step is a cup object
> with one attribute, its ounce size. Here's a "constructor"
>
> cup :: t1 -> (t1 -> t2) -> t2
> cup flOz = \message -> message flOz
>
> so this returns upon use
>
> > myCup = cup 6
>
> myCup which has "internally" a lambda function
>
> (\message -> message) 6
>
> waiting, correct?

Not exactly. `myCup` is a function with takes another function as input

    λ> :t myCup
    myCup :: (Integer -> t2) -> t2

and the body looks like this

    \f -> f 6

`\f -> f 6`  is different from  `(\f -> f) 6`!


> Now a "method"
>
> getOz aCup = aCup (\foz -> foz)
>
> creates a closure on the lambda function (\foz -> foz) . So upon calling
>
> > getOz myCup
> 6
>
> I'm guessing myCup (\foz -> foz) was evaluated, but I don't understand how
> the 6 that went in as the bound variable in the constructor came out again
> with getOz.

To recap, `myCup` expands to:

    myCup
    cup 6
    \message -> message 6

Now, applying `getOz` to it…

    getOz myCup
    myCup (\foz -> foz)
    (\message -> message 6) (\foz -> foz)
    (\foz -> foz) 6
    6

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: OOP exercise with closures

Lawrence Bottorff-2
Thanks! Since I studied lambda calc a bit I understand the steps

(\message -> message 6) (\foz -> foz)
(\foz -> foz) 6
 6

But this is so bizarre! To have a "constructor" that creates an instance, which is then really a holder of a lambda calculation is a mind-bender.

On Tue, Dec 29, 2020 at 4:07 PM Francesco Ariis <[hidden email]> wrote:
Il 29 dicembre 2020 alle 15:43 Lawrence Bottorff ha scritto:
> Okay, I'm in Lesson 10 of *Get Programming with Haskell * and we're
> creating an OOP-like world with closures. The first step is a cup object
> with one attribute, its ounce size. Here's a "constructor"
>
> cup :: t1 -> (t1 -> t2) -> t2
> cup flOz = \message -> message flOz
>
> so this returns upon use
>
> > myCup = cup 6
>
> myCup which has "internally" a lambda function
>
> (\message -> message) 6
>
> waiting, correct?

Not exactly. `myCup` is a function with takes another function as input

    λ> :t myCup
    myCup :: (Integer -> t2) -> t2

and the body looks like this

    \f -> f 6

`\f -> f 6`  is different from  `(\f -> f) 6`!


> Now a "method"
>
> getOz aCup = aCup (\foz -> foz)
>
> creates a closure on the lambda function (\foz -> foz) . So upon calling
>
> > getOz myCup
> 6
>
> I'm guessing myCup (\foz -> foz) was evaluated, but I don't understand how
> the 6 that went in as the bound variable in the constructor came out again
> with getOz.

To recap, `myCup` expands to:

    myCup
    cup 6
    \message -> message 6

Now, applying `getOz` to it…

    getOz myCup
    myCup (\foz -> foz)
    (\message -> message 6) (\foz -> foz)
    (\foz -> foz) 6
    6

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners