# Lambda Functions

8 messages
Open this post in threaded view
|

## Lambda Functions

 Okay, thanks everyone for the help with the last question; I've got another one for you if you are keen. It's short and sweet. You can easily define a lambda expression that takes a tuple - e.g. in ghci  > let foo = \(x,y) -> 42 foo :: (t, t1) -> Integer  > foo (5,5) 42 Yay. Now that isn't a very exciting function. Tt takes two anythings and gives you a nice meaningful number. Now let us say for some perverse reason I want to make a lambda to test for equality. That is, reimplement the functionality of (==) using, well, (==).  > let foo2 = \(x,y) -> x == y foo2 :: ((), ()) -> Bool Uh-oh. Now things are getting a little odd. I am not entirely sure what that type signature means (I was expecting to see something about the types having to be the same and an instance of the Eq class but alas..) The function certainly doesn't do what I want it to:  > foo2 (5,5)     No instance for (Num ())       arising from the literal `5' at :1:6     Possible fix: add an instance declaration for (Num ())     In the expression: 5     In the first argument of `foo2', namely `(5, 5)'     In the expression: foo2 (5, 5) This is itself a stupid problem, but it is a distilled version of some trouble I was having writing a filter that works on a list of tuples. Any pointers or slaps in the face for being too stupid warmly welcomed. I have already tried my usual trick of smothering the thing parentheses but it appeared to be all in vain. All the best, Philip
Open this post in threaded view
|

## Lambda Functions

 On 26 Feb 2009, at 23:07, Philip Scott wrote: > Okay, thanks everyone for the help with the last question; I've got   > another one for you if you are keen. It's short and sweet. > > You can easily define a lambda expression that takes a tuple - e.g.   > in ghci > > > let foo = \(x,y) -> 42 > foo :: (t, t1) -> Integer > > > foo (5,5) > 42 > > Yay. Now that isn't a very exciting function. Tt takes two anythings   > and gives you a nice meaningful number. Now let us say for some   > perverse reason I want to make a lambda to test for equality. That   > is, reimplement the functionality of (==) using, well, (==). > > > let foo2 = \(x,y) -> x == y > > foo2 :: ((), ()) -> Bool > > Uh-oh. Now things are getting a little odd. I am not entirely sure   > what that type signature means (I was expecting to see something   > about the types having to be the same and an instance of the Eq   > class but alas..) The function certainly doesn't do what I want it to: > > > foo2 (5,5) > >   No instance for (Num ()) >     arising from the literal `5' at :1:6 >   Possible fix: add an instance declaration for (Num ()) >   In the expression: 5 >   In the first argument of `foo2', namely `(5, 5)' >   In the expression: foo2 (5, 5) > > This is itself a stupid problem, but it is a distilled version of   > some trouble I was having writing a filter that works on a list of   > tuples. Any pointers or slaps in the face for being too stupid   > warmly welcomed. I have already tried my usual trick of smothering   > the thing parentheses but it appeared to be all in vain. I'm not 100% certain here, so someone may correct me, but I think this   is what's going on: foo2 has no arguments.  Because of this, ghci makes it a CAF.  At this   point, the monomorphism restriction kicks in, and the CAF has to be   monomorphic.  ghc then chooses a type for it, and defaulting choses   the most simple type it can find ? () (this is the type that contains   one value ? () ). If instead, you do let foo3 (x,y) = x == y, you will get the type you   expected. Another way to write it ofc would simply be uncurry (==). Bob
Open this post in threaded view
|

## Lambda Functions

 On Thu, Feb 26, 2009 at 7:25 PM, Thomas Davie <[hidden email]> wrote: > I'm not 100% certain here, so someone may correct me, but I think this is > what's going on: [snip] Yep, that's right. Is it just me or the monomorphism restriction suddenly became the hot topic here on beginners? > Another way to write it ofc would simply be uncurry (==). Better yet, write a type signature. I highly recommend writing type signatures for *all* top-level definitions, including non-exported ones: - You avoid most cases where the monomorphism restriction would bother you. - You avoid type errors on other functions (sometimes you make a mistake but the code type checks with a wrong signature, and the type error shows up only when you use the function elsewhere). - It gives you some insights before implementing, and helps whoever reads your code. - It allows you to specialize the code when polymorphism is not needed. Probably there are other reasons as well, but these are the most prominent. -- Felipe.
Open this post in threaded view
|

## Lambda Functions

 On Thu, Feb 26, 2009 at 07:51:32PM -0300, Felipe Lessa wrote: > > Better yet, write a type signature. I highly recommend writing type > signatures for *all* top-level definitions, including non-exported > ones: > > - It gives you some insights before implementing Hear, hear!  If you can't write down the intended type of a function, you have very little hope of implementing it correctly. =) -Brent
Open this post in threaded view
|

## Lambda Functions

 In reply to this post by Felipe Lessa Excellent list. It seems like every time I hear about a problem with the MMR, I go "wow, how come I never ran across that? oh yeah, because I write type signatures..." On Thu, Feb 26, 2009 at 5:51 PM, Felipe Lessa <[hidden email]>wrote: > On Thu, Feb 26, 2009 at 7:25 PM, Thomas Davie <[hidden email]> wrote: > > I'm not 100% certain here, so someone may correct me, but I think this is > > what's going on: > [snip] > > Yep, that's right. Is it just me or the monomorphism restriction > suddenly became the hot topic here on beginners? > > > Another way to write it ofc would simply be uncurry (==). > > Better yet, write a type signature. I highly recommend writing type > signatures for *all* top-level definitions, including non-exported > ones: > > - You avoid most cases where the monomorphism restriction would bother you. > > - You avoid type errors on other functions (sometimes you make a > mistake but the code type checks with a wrong signature, and the type > error shows up only when you use the function elsewhere). > > - It gives you some insights before implementing, and helps whoever > reads your code. > > - It allows you to specialize the code when polymorphism is not needed. > > Probably there are other reasons as well, but these are the most prominent. > > -- > Felipe. > _______________________________________________ > Beginners mailing list > [hidden email] > http://www.haskell.org/mailman/listinfo/beginners> -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20090226/8c993f12/attachment.htm
Open this post in threaded view
|

## Lambda Functions

 On 26/02/2009, Andrew Wagner <[hidden email]> wrote: > Excellent list. It seems like every time I hear about a problem with the > MMR, I go "wow, how come I never ran across that? oh yeah, because I write > type signatures..." Certainly. Still, it seems relatively easy to bump into it when tinkering on ghci. Out of interest, what are the disadvantages to blanket turning off the restriction? -- Matt