flatMap (with a capital M)

-Ross

On Jan 18, 2010, at 5:21 PM, pabraham wrote:

> Hi Naftoli,
> 
> The code I have is:
> 
> def allexpenses(expenseTemplate: NodeSeq): NodeSeq = Expense.findAll(By
> (Expense.month,m.toLong)).flatmap ({ month =>
>  bind("month", expenseTemplate,
>       "name" -> Text( month.item ),
>       "amount" -> Text( month.amount )
>  )
> })
> bind("thismonth", xhtml, "expenseitem" -> allexpenses _)
> 
> which gives the error: value flatmap is not a member of List
> [demo.expenses.model.Expense]
> 
> From what you've said, I'm not sure how to remove the flatmap without
> generating another error.  I realise this is a bit cheeky, but please
> humour me and rewrite my code above to remove the flatmap and errors.
> 
> Also given an ID, how can I create an instance of a Month class whose
> ID matches that ID?
> 
> Regards,
> 
> Paul.
> 
> 
> On 18 Jan, 21:57, Naftoli Gugenheim <[email protected]> wrote:
>> val l = List(1,2,3)
>> l.map(x => x * 2)  ==  List(2,4,6)
>> So map take as its argument a function that transforms every member of the 
>> list.
>> flatmap is similar but instead of the new List *consisting of* the 
>> transformed elements, it consists of the *concatenation* of the results of 
>> the function (which must be concatenatable). So
>> l.flatmap(x => List(x, x * 2))  ==  List(1,2) ++ List(2,4) ++ List(3,6)  ==  
>> List(1,2,2,4,3,6)
>> Since bind returns a NodeSeq, if you would return the result of bind from a 
>> function you pass to *map* you would have a List of NodeSeq. Flatmap means 
>> you'll get the NodeSeq for each List element concatenated into one long 
>> NodeSeq.
>> So your code needs to continue
>>   ...flatmap { curExpense =>
>>       bind("prefix", expenseTemplate, ...)
>> 
>> }
>> 
>> -------------------------------------
>> 
>> pabraham<[email protected]> wrote:
>> 
>> Hi Adam,
>> 
>> Thanks for your advice.  Unfortunately if I paste your code, I get
>> "error: not found: value expensesformonth".
>> 
>> I need to convert my "m" value to an instance of Month where the ID of
>> this instance is "m", but I can't work out how.
>> 
>> I then tried this:
>> 
>> def allexpenses(expenseTemplate: NodeSeq): NodeSeq = Expense.findAll(By
>> (Expense.month,m.toLong)).flatmap
>> 
>> but the findAll() gives a List[] not a flatmap, and my Scala isn't
>> good enough to convert from one to the other!
>> 
>> Regards,
>> 
>> Paul.
>> 
>> On 18 Jan, 08:32, Adam Warski <[email protected]> wrote:
>> 
>>> Hello,
>> 
>>>> I have HTML to print out expenses for a given month (i.e. URL = .../
>>>> month/12):
>> 
>>>> <lift:MonthPage.summary>
>>>> ...
>>>> <thismonth:expenseitem>
>>>> <tr>
>>>>        <td><month:item /></td>
>>>>        <td align="right"><month:amount /></td>
>>>> </tr>
>>>> </thismonth:expenseitem>
>>>> ...
>>>> </lift:MonthPage.summary>
>> 
>>>> The area I'm having problems with is the code to drive the above
>>>> HTML.  I need something like:
>> 
>>>> class MonthPage {
>>>>  def summary( xhtml : NodeSeq ) : NodeSeq = S.param("month") match {
>>>>    case Full(m) => {
>>>>      val allexpenses : NodeSeq = expensesformonth.flatmap({ month =>
>>>>          bind("month", chooseTemplate("thismonth", "expenseitem",
>>>> xhtml),
>>>>              "name" -> Text( month.item ),
>>>>              "amount" -> Text( month.amount )
>>>>          )
>>>>        })
>>>>      bind("thismonth", xhtml, "expenseitem" -> allexpenses)
>>>>    }
>>>>    case _ => {
>>>>      Text( "Not a valid month." )
>>>>    }
>>>>  }
>>>> }
>> 
>>> I think you're almost there.
>>> Try making the "allexpenses" val a function (def) NodeSeq => NodeSeq. The 
>>> function takes the "template" of the month and returns it with bound 
>>> values. So something like:
>> 
>>> class MonthPage {
>>>  def summary( xhtml : NodeSeq ) : NodeSeq = S.param("month") match {
>>>    case Full(m) => {
>>>      def allexpenses(expenseTemplate: NodeSeq): NodeSeq = 
>>> expensesformonth.flatmap({ month =>
>>>          bind("month", expenseTemplate,
>>>              "name" -> Text( month.item ),
>>>              "amount" -> Text( month.amount )
>>>          )
>>>        })
>>>      bind("thismonth", xhtml, "expenseitem" -> allexpenses _)
>>>    }
>>>    case _ => {
>>>      Text( "Not a valid month." )
>>>    }
>>>  }
>> 
>>> }
>> 
>>> No need to lookup the right template then using chooseTemplate, as the 
>>> method receives the appropriate xhtml.
>> 
>>> --
>>> Adam
>> 
>> --
>> You received this message because you are subscribed to the Google Groups 
>> "Lift" group.
>> To post to this group, send email to [email protected].
>> To unsubscribe from this group, send email to 
>> [email protected].
>> For more options, visit this group 
>> athttp://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 [email protected].
> To unsubscribe from this group, send email to 
> [email protected].
> 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 [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.


Reply via email to