Improve my lambda expressions

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Improve my lambda expressions

Patrick Browne
The code below provides a distance function that works for points and moving point.
I am happy with the result, but I have a problem with the lambda expressions.
Instead of supplying an argument to each 'mpXX', is it possible to have a single lambda argument on the entire final 'md' function? (e.g. 'md 2')
Thanks in advance,
Pat

data Point a = Point { abscissa :: a, ordinate :: a } deriving Show
dist a b = sqrt (((abscissa a) - (abscissa b))^2 + ((ordinate a) - (ordinate b))^2)

-- Sttic points
p1, p2 :: Point Float
p1 = Point 0.0 0.0
p2 = Point 4.0 4.0
d = dist p1 p2


-- Moving points
mp1, mp2 :: Point Float
mp1x = (\t -> 4.0 + 0.5 * t)
mp1y = (\t -> 4.0 - 0.5 * t)
mp1 = Point (mp1x 2) (mp1y  2)
mp2x  = (\t -> 0.0 + 1.0 * t)
mp2y  = (\t -> 0.0 - 1.0 * t)
mp2 = Point (mp2x 2) (mp2y 2)
md = dist mp1 mp2

This email originated from DIT. If you received this email in error, please delete it from your system. Please note that if you are not the named addressee, disclosing, copying, distributing or taking any action based on the contents of this email or attachments is prohibited. www.dit.ie

Is ó ITBÁC a tháinig an ríomhphost seo. Má fuair tú an ríomhphost seo trí earráid, scrios de do chóras é le do thoil. Tabhair ar aird, mura tú an seolaí ainmnithe, go bhfuil dianchosc ar aon nochtadh, aon chóipeáil, aon dáileadh nó ar aon ghníomh a dhéanfar bunaithe ar an ábhar atá sa ríomhphost nó sna hiatáin seo. www.dit.ie

Tá ITBÁC ag aistriú go Gráinseach Ghormáin – DIT is on the move to Grangegorman


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

Re: Improve my lambda expressions

Silent Leaf
yes you can, it's actually better to encapsulate all "lambdas" and intermediate values inside one function, provided you never use them anywhere else.
i advise using "where" as such:

md n = dist (Point (fx n) (fy n)) (Point (gx n) (gy n))
  where fx n = 4.0 + 0.5 * n
        fy n = 4.0 - 0.5 * n
        gx n = n * 1.0
        gy n = n * (-1.0)
-- then you can call "foo = md 2"

it's more idiomatic to use where, i believe. however you can also choose to define the helpers before the expression defining the function, using "let ... in" like that:

md n = let fx n = 4.0 + 0.5 * n
           fy n = 4.0 - 0.5 * n
           gx n = n * 1.0
           gy n = n * (-1.0)
       in dist (Point (fx n) (fy n)) (Point (gx n) (gy n))

be careful about the alignment. both ways are (in this example) strictly equivalent, it all depends on circumstances and taste.

mind you if you don't want a function to be reused, merely one single value foo = md 2, you can always just write directly:
foo = dist (Point (fx 2) (fy 2)) (Point (gx 2) (gy 2))
  where fx n = 4.0 + 0.5 * n
        fy n = 4.0 - 0.5 * n
        gx n = n * 1.0
        gy n = n * (-1.0)

2017-06-26 11:38 GMT+02:00 PATRICK BROWNE <[hidden email]>:
The code below provides a distance function that works for points and moving point.
I am happy with the result, but I have a problem with the lambda expressions.
Instead of supplying an argument to each 'mpXX', is it possible to have a single lambda argument on the entire final 'md' function? (e.g. 'md 2')
Thanks in advance,
Pat

data Point a = Point { abscissa :: a, ordinate :: a } deriving Show
dist a b = sqrt (((abscissa a) - (abscissa b))^2 + ((ordinate a) - (ordinate b))^2)

-- Sttic points
p1, p2 :: Point Float
p1 = Point 0.0 0.0
p2 = Point 4.0 4.0
d = dist p1 p2


-- Moving points
mp1, mp2 :: Point Float
mp1x = (\t -> 4.0 + 0.5 * t)
mp1y = (\t -> 4.0 - 0.5 * t)
mp1 = Point (mp1x 2) (mp1y  2)
mp2x  = (\t -> 0.0 + 1.0 * t)
mp2y  = (\t -> 0.0 - 1.0 * t)
mp2 = Point (mp2x 2) (mp2y 2)
md = dist mp1 mp2

This email originated from DIT. If you received this email in error, please delete it from your system. Please note that if you are not the named addressee, disclosing, copying, distributing or taking any action based on the contents of this email or attachments is prohibited. www.dit.ie

Is ó ITBÁC a tháinig an ríomhphost seo. Má fuair tú an ríomhphost seo trí earráid, scrios de do chóras é le do thoil. Tabhair ar aird, mura tú an seolaí ainmnithe, go bhfuil dianchosc ar aon nochtadh, aon chóipeáil, aon dáileadh nó ar aon ghníomh a dhéanfar bunaithe ar an ábhar atá sa ríomhphost nó sna hiatáin seo. www.dit.ie

Tá ITBÁC ag aistriú go Gráinseach Ghormáin – DIT is on the move to Grangegorman


_______________________________________________
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Improve my lambda expressions

Frerich Raabe
In reply to this post by Patrick Browne
On 2017-06-26 11:38, PATRICK BROWNE wrote:
> The code below provides a distance function that works for points and moving
> point.
> I am happy with the result, but I have a problem with the lambda
> expressions.

[..]

> -- Sttic points
> p1, p2 :: Point Float
> p1 = Point 0.0 0.0
> p2 = Point 4.0 4.0
> d = dist p1 p2
>
> -- Moving points
> mp1, mp2 :: Point Float
> mp1x = (\t -> 4.0 + 0.5 * t)
> mp1y = (\t -> 4.0 - 0.5 * t)
> mp1 = Point (mp1x 2) (mp1y  2)
> mp2x  = (\t -> 0.0 + 1.0 * t)
> mp2y  = (\t -> 0.0 - 1.0 * t)
> mp2 = Point (mp2x 2) (mp2y 2)
> md = dist mp1 mp2

Maybe you could reduce the number of lambda expressions by extracting common
logic. It seems to me that 'mp1' and 'mp2' are moved versions of the same
point (2,2) except that they apply different functions to the coordinates.
These functions follow a pattern (a factor is applied to the component and
then an 'offset' is added).

For instance, it might be worthwhile to define

   movePoint :: Float -> Float -> Point -> Point
   movePoint offset factor (Point x y) = Point (offset + factor * x) (offset -
factor * y)

...such that you could then define

md = let p = Point 2 2 in dist (movePoint 4 0.5 p) (movePoint 0 1 p)

--
Frerich Raabe - [hidden email]
www.froglogic.com - Multi-Platform GUI Testing
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Improve my lambda expressions

Patrick Browne
In reply to this post by Patrick Browne
Thanks for all your help.
I was unaware that there was a relation between let/where and lambdas.
Here is my effort to use a single lamda
md3 n = (\n -> (dist  (Point (4.0 + 0.5 * n) (4.0 - 0.5 * n)) (Point (n * 1.0) ( n * (-1.0))))) n

I imagine that this function could be written without lambdas, let, or where.
Is it generally true the all/most functions could be written without lambdas, let, or where?

Thanks,
Pat

 

On 26 June 2017 at 12:04, Frerich Raabe <[hidden email]> wrote:
On 2017-06-26 11:38, PATRICK BROWNE wrote:
The code below provides a distance function that works for points and moving point.
I am happy with the result, but I have a problem with the lambda expressions.

[..]

-- Sttic points
p1, p2 :: Point Float
p1 = Point 0.0 0.0
p2 = Point 4.0 4.0
d = dist p1 p2

-- Moving points
mp1, mp2 :: Point Float
mp1x = (\t -> 4.0 + 0.5 * t)
mp1y = (\t -> 4.0 - 0.5 * t)
mp1 = Point (mp1x 2) (mp1y  2)
mp2x  = (\t -> 0.0 + 1.0 * t)
mp2y  = (\t -> 0.0 - 1.0 * t)
mp2 = Point (mp2x 2) (mp2y 2)
md = dist mp1 mp2

Maybe you could reduce the number of lambda expressions by extracting common logic. It seems to me that 'mp1' and 'mp2' are moved versions of the same point (2,2) except that they apply different functions to the coordinates. These functions follow a pattern (a factor is applied to the component and then an 'offset' is added).

For instance, it might be worthwhile to define

  movePoint :: Float -> Float -> Point -> Point
  movePoint offset factor (Point x y) = Point (offset + factor * x) (offset - factor * y)

...such that you could then define

md = let p = Point 2 2 in dist (movePoint 4 0.5 p) (movePoint 0 1 p)

--
Frerich Raabe - [hidden email]
www.froglogic.com - Multi-Platform GUI Testing


This email originated from DIT. If you received this email in error, please delete it from your system. Please note that if you are not the named addressee, disclosing, copying, distributing or taking any action based on the contents of this email or attachments is prohibited. www.dit.ie

Is ó ITBÁC a tháinig an ríomhphost seo. Má fuair tú an ríomhphost seo trí earráid, scrios de do chóras é le do thoil. Tabhair ar aird, mura tú an seolaí ainmnithe, go bhfuil dianchosc ar aon nochtadh, aon chóipeáil, aon dáileadh nó ar aon ghníomh a dhéanfar bunaithe ar an ábhar atá sa ríomhphost nó sna hiatáin seo. www.dit.ie

Tá ITBÁC ag aistriú go Gráinseach Ghormáin – DIT is on the move to Grangegorman


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

Re: Improve my lambda expressions

Frerich Raabe
On 2017-06-27 18:35, PATRICK BROWNE wrote:
> Thanks for all your help.
> I was unaware that there was a relation between let/where and lambdas.
> Here is my effort to use a single lamda
> md3 n = (\n -> (dist  (Point (4.0 + 0.5 * n) (4.0 - 0.5 * n)) (Point (n *
> 1.0) ( n * (-1.0))))) n
>
> I imagine that this function could be written without lambdas, let, or
> where.

Indeed, it could. Note that your definition has the form

   md3 n = (\n -> (dist )) n

I.e. the expression 'md3 n' is equivalent to the expression '(\n -> (dist
..)) n', which means 'apply the lambda expression to n'. You don't need the
lambda expression if you apply it to a given argument directly though, i.e.
the above definition is equivalent to

   md3 n = dist ..

> Is it generally true the all/most functions could be written without
> lambdas, let, or where?

I believe it is true since you could define any function as a global
definition (i.e. not a nested scope as in let..in or where).

--
Frerich Raabe - [hidden email]
www.froglogic.com - Multi-Platform GUI Testing
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Loading...