Re: [Lift] Safe handling of long params

2010-01-05 Thread Jim Wise
Ross Mellgren  writes:

> In your case, asLong is:
>
> def asLong(s: String): Box[Long]
>
> So if you used map:
>
> Full("1234").map(asLong) // result is Full(Full(1234)), because the  
> result of asLong went into the Full that map creates
>
> Conversely, flatMap removes a level of structure:
>
> Full("1234").flatMap(asLong) // result is Full(1234)
>
> Hope that helps,

It does, thanks!
-- 
Jim Wise
jw...@draga.com


pgpob1HvlWv3g.pgp
Description: PGP signature


Re: [Lift] Safe handling of long params

2010-01-05 Thread Ross Mellgren
They aren't. Here are the type signatures for map and flatMap, from  
Box (the type on Seq is the same, but not specialized to the Box  
return type):

def map[B](f: A => B): Box[B]
def flatMap[B](f: A => Box[B]): Box[B]

The key is the return type of "f" -- in map, it always returns what  
goes in the Full box, whereas in flatMap it returns any type of box  
(which could be empty, failure, etc).

To illustrate better, here are some examples:

def f1(i: Int): String = i.toString

Full(1).map(f1) // result is Full("1")
Full(2).map(f1) // result is Full("2")
Empty.map(f1) // result is Empty (f1 never applied)
Failure(...).map(f1) // result is Failure (f1 never applied)

def f2(i: Int): Box[String] = if (i % 2 == 0) Full(i.toString) else  
Failure("number is not even")

Full(1).flatMap(f2) // result is Failure("number is not even", ...)
Full(2).flatMap(f2) // result is Full("2")
Empty.flatMap(f2) // result is Empty (f2 never applied)
Failure(...).flatMap(f2) // result is Failure (f2 never applied)

As you can see, functions passed to map can never "fail", that is,  
they can never cause a Box to become empty. The result of a map is as  
empty as the input to it.

Conversely, with flatMap the function passed in can "fail", making a  
non-Full box.

So, flatMap is used for chaining together computations (functions)  
that can fail, whereas map is used for computations that can't fail  
(barring exceptions)

This ties in with the collection-like view of a Box, which can be  
views as a single-element collection (Full) or empty collection  
(Empty, Failure) where the empty collection might have some extra  
information about why the collection is empty.

In your case, asLong is:

def asLong(s: String): Box[Long]

So if you used map:

Full("1234").map(asLong) // result is Full(Full(1234)), because the  
result of asLong went into the Full that map creates

Conversely, flatMap removes a level of structure:

Full("1234").flatMap(asLong) // result is Full(1234)

Hope that helps,
-Ross


On Jan 5, 2010, at 10:45 AM, Jim Wise wrote:

>>>
>>> I can answer b) -- S.param("image").flatMap(asLong)
>>>
>>> asLong comes from BasicTypesHelpers.
>>>
>>> -Ross
>
> One more quick question about this, more of a Scala question really:
> I've noticed both here and in the examples that there is a tendency to
> use flatMap() instead of map().  I understand the differences between
> the two, but am not sure why flatMap is preferred when there aren't
> Lists involved.  Any reason?  Aren't the two interchangeable in this
> case?
>
> Thanks,
> -- 
>   Jim Wise
>   jw...@draga.com

--

You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Safe handling of long params

2010-01-05 Thread Naftoli Gugenheim
map would result in a Box[Box[Long]]

-
Jim Wise wrote:

>>
>> I can answer b) -- S.param("image").flatMap(asLong)
>>
>> asLong comes from BasicTypesHelpers.
>>
>> -Ross

One more quick question about this, more of a Scala question really:
I've noticed both here and in the examples that there is a tendency to
use flatMap() instead of map().  I understand the differences between
the two, but am not sure why flatMap is preferred when there aren't
Lists involved.  Any reason?  Aren't the two interchangeable in this
case?

Thanks,
-- 
Jim Wise
jw...@draga.com

--

You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Safe handling of long params

2010-01-05 Thread Jim Wise
>>
>> I can answer b) -- S.param("image").flatMap(asLong)
>>
>> asLong comes from BasicTypesHelpers.
>>
>> -Ross

One more quick question about this, more of a Scala question really:
I've noticed both here and in the examples that there is a tendency to
use flatMap() instead of map().  I understand the differences between
the two, but am not sure why flatMap is preferred when there aren't
Lists involved.  Any reason?  Aren't the two interchangeable in this
case?

Thanks,
-- 
Jim Wise
jw...@draga.com


pgpAa00XxSc5y.pgp
Description: PGP signature


Re: [Lift] Safe handling of long params

2010-01-04 Thread Jim Wise
Aha!

Thanks,

Sent from my iPhone

On Jan 4, 2010, at 16:45, Ross Mellgren  wrote:

>
> I can answer b) -- S.param("image").flatMap(asLong)
>
> asLong comes from BasicTypesHelpers.
>
> -Ross
>
> On Jan 4, 2010, at 4:42 PM, Jim Wise wrote:
>
>>
>> So, in my endless retweaking of this code, getting better (and
>> learning
>> more lift) on each pass, I've got a rewrite rule like this
>>
>>case RewriteRequest(ParsePath("image" :: image :: Nil, _, _,
>> _), _, _) =>
>>  RewriteResponse("viewImage" :: Nil, Map("image" -> image))
>>
>> which is (eventually) handled by a snippet like this:
>>
>> def doShowOne(in: NodeSeq): NodeSeq =
>>   S.param("image").map(_.toLong) match {
>> case Full(selected) =>
>>   ImageInfo.findByKey(selected) match {
>> case Full(i) =>
>>   bind(...)
>> case _ =>
>>   S.error("No such image!")
>>   }
>> case _ =>
>>   S.redirectTo("/images")
>>   }
>>
>> Which works well if the referenced path component is the id of an
>> existing image, or of a nonexistent image -- and throws an exception
>> if
>> the last path component can't be parsed as a long.
>>
>> I can catch the exception, of course, but I kinda feel there must  
>> be a
>> cleaner way to do this -- either by not matching in the rewriting PF
>> if
>> the positional paramter "image" is not parseable as a long, or by
>> making
>> this another layer of casing in the snippet.
>>
>> So, two questions:
>>
>> a.) is there an idiom for this?
>>
>> b.) is there a good way to test if a String (or better, a Box
>> [String])
>> is convertable toLong without a try/catch?
>>
>> Thanks again,
>> -- 
>>Jim Wise
>>jw...@draga.com
>
> --
>
> You received this message because you are subscribed to the Google  
> Groups "Lift" group.
> To post to this group, send email to lift...@googlegroups.com.
> To unsubscribe from this group, send email to 
> liftweb+unsubscr...@googlegroups.com 
> .
> For more options, visit this group at 
> http://groups.google.com/group/liftweb?hl=en 
> .
>

--

You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Safe handling of long params

2010-01-04 Thread Timothy Perrett
Ah right yeah - I thought it was implicit :)

On 4 Jan 2010, at 22:09, Ross Mellgren wrote:

> Nope, it's not a implicit extension of String or anything, it's just a  
> plain method def asLong(s: String): Box[Long] in BasicTypesHelpers
> 
> -Ross
> 
> On Jan 4, 2010, at 5:08 PM, Timothy Perrett wrote:
> 
>> Shouldnt that be:
>> 
>> S.param("image").flatMap(_.asLong)
>> 
>> Cheers, Tim
>> 
>> On 4 Jan 2010, at 21:45, Ross Mellgren wrote:
>> 
>>> S.param("image").flatMap(asLong)
>> 
>> --
>> 
>> You received this message because you are subscribed to the Google  
>> Groups "Lift" group.
>> To post to this group, send email to lift...@googlegroups.com.
>> To unsubscribe from this group, send email to 
>> liftweb+unsubscr...@googlegroups.com 
>> .
>> For more options, visit this group at 
>> http://groups.google.com/group/liftweb?hl=en 
>> .
>> 
>> 
> 
> --
> 
> You received this message because you are subscribed to the Google Groups 
> "Lift" group.
> To post to this group, send email to lift...@googlegroups.com.
> To unsubscribe from this group, send email to 
> liftweb+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/liftweb?hl=en.
> 
> 
> 

--

You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Safe handling of long params

2010-01-04 Thread Ross Mellgren
Nope, it's not a implicit extension of String or anything, it's just a  
plain method def asLong(s: String): Box[Long] in BasicTypesHelpers

-Ross

On Jan 4, 2010, at 5:08 PM, Timothy Perrett wrote:

> Shouldnt that be:
>
> S.param("image").flatMap(_.asLong)
>
> Cheers, Tim
>
> On 4 Jan 2010, at 21:45, Ross Mellgren wrote:
>
>> S.param("image").flatMap(asLong)
>
> --
>
> You received this message because you are subscribed to the Google  
> Groups "Lift" group.
> To post to this group, send email to lift...@googlegroups.com.
> To unsubscribe from this group, send email to 
> liftweb+unsubscr...@googlegroups.com 
> .
> For more options, visit this group at 
> http://groups.google.com/group/liftweb?hl=en 
> .
>
>

--

You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Safe handling of long params

2010-01-04 Thread Timothy Perrett
Shouldnt that be:

S.param("image").flatMap(_.asLong)

Cheers, Tim

On 4 Jan 2010, at 21:45, Ross Mellgren wrote:

> S.param("image").flatMap(asLong)

--

You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Safe handling of long params

2010-01-04 Thread Ross Mellgren

I can answer b) -- S.param("image").flatMap(asLong)

asLong comes from BasicTypesHelpers.

-Ross

On Jan 4, 2010, at 4:42 PM, Jim Wise wrote:

>
> So, in my endless retweaking of this code, getting better (and  
> learning
> more lift) on each pass, I've got a rewrite rule like this
>
>   case RewriteRequest(ParsePath("image" :: image :: Nil, _, _,  
> _), _, _) =>
> RewriteResponse("viewImage" :: Nil, Map("image" -> image))
>
> which is (eventually) handled by a snippet like this:
>
>  def doShowOne(in: NodeSeq): NodeSeq =
>S.param("image").map(_.toLong) match {
>  case Full(selected) =>
>ImageInfo.findByKey(selected) match {
>  case Full(i) =>
>bind(...)
>  case _ =>
>S.error("No such image!")
>}
>  case _ =>
>S.redirectTo("/images")
>}
>
> Which works well if the referenced path component is the id of an
> existing image, or of a nonexistent image -- and throws an exception  
> if
> the last path component can't be parsed as a long.
>
> I can catch the exception, of course, but I kinda feel there must be a
> cleaner way to do this -- either by not matching in the rewriting PF  
> if
> the positional paramter "image" is not parseable as a long, or by  
> making
> this another layer of casing in the snippet.
>
> So, two questions:
>
>  a.) is there an idiom for this?
>
>  b.) is there a good way to test if a String (or better, a Box 
> [String])
>  is convertable toLong without a try/catch?
>
> Thanks again,
> -- 
>   Jim Wise
>   jw...@draga.com

--

You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




[Lift] Safe handling of long params

2010-01-04 Thread Jim Wise

So, in my endless retweaking of this code, getting better (and learning
more lift) on each pass, I've got a rewrite rule like this

case RewriteRequest(ParsePath("image" :: image :: Nil, _, _, _), _, _) 
=>
  RewriteResponse("viewImage" :: Nil, Map("image" -> image))

which is (eventually) handled by a snippet like this:

  def doShowOne(in: NodeSeq): NodeSeq =
S.param("image").map(_.toLong) match {
  case Full(selected) =>
ImageInfo.findByKey(selected) match {
  case Full(i) =>
bind(...)
  case _ =>
S.error("No such image!")
}
  case _ =>
S.redirectTo("/images")
}

Which works well if the referenced path component is the id of an
existing image, or of a nonexistent image -- and throws an exception if
the last path component can't be parsed as a long.

I can catch the exception, of course, but I kinda feel there must be a
cleaner way to do this -- either by not matching in the rewriting PF if
the positional paramter "image" is not parseable as a long, or by making
this another layer of casing in the snippet.

So, two questions:

  a.) is there an idiom for this?

  b.) is there a good way to test if a String (or better, a Box[String])
  is convertable toLong without a try/catch?

Thanks again,
-- 
Jim Wise
jw...@draga.com


pgpMvTKeojjrI.pgp
Description: PGP signature