I kind of suck at recursion (which is why im working on this) and I'm having trouble figuring out how to do this: ("Hello" foldLeft(1))((x, y) => x * y.toInt)
recursively. Any thoughts?
Asked
Active
Viewed 592 times
1

LuxuryMode
- 33,401
- 34
- 117
- 188
-
2Better: `"Hello".map(_.toInt).product` – Landei Jul 04 '12 at 06:34
4 Answers
5
scala> def r(s : String) : Int = {
| s match {
| case "" => 1
| case _ => s.head.toInt * r(s.tail)
| }
| }
r: (s: String)Int
scala> r("hello")
res4: Int = 714668928

Larry OBrien
- 8,484
- 1
- 41
- 75
-
@LuxuryMode -- No. Put the `@tailrec` annotation on the method and the compiler will complain if it is not – Dave L. Jul 04 '12 at 01:11
-
2@LuxuryMode: For a function to be tail recursive, the last expression must be a call to the function itself. In this case, the last expression is the multiplication. – Kaito Jul 04 '12 at 01:17
3
I transformed the other answer into a tail recursive version I think:
@tailrec
def r(acc: Int, s: String): Int = {
s match {
case "" => acc
case _ => r(s.head.toInt * acc, s.tail)
}
}
print(r(1, "hello"))
See this answer for general advice on transforming functions like these into a tail recursive format:
-
thanks David, this is excellent! Did not know about the @tailrec annotation..so cool. – LuxuryMode Jul 04 '12 at 02:24
-
2I'd rather write `r(s:String, acc:Int = 1)`, so you don't have to initialize the accumulator when you call the function. – Landei Jul 04 '12 at 06:13
1
Here's a tail recursive version using an accumulator. This version has a clean API too.
import scala.annotation.tailrec
def unicodeProduct(string: String): Int = {
@tailrec
def unicodeProductAcc(string: String, acc: Int): Int = {
string match{
case "" => acc
case _ => unicodeProductAcc(string.tail, string.head.toInt * acc )
}
}
unicodeProductAcc(string, 1)
}
scala> :load unicodeProduct.scala
Loading unicodeProduct.scala...
import scala.annotation.tailrec
unicodeProduct: (string: String)Int
scala> unicodeProduct("hello")
res0: Int = 714668928

Brian
- 20,195
- 6
- 34
- 55
-
The ability to have nested functions is so sweet. Lets you write really clean APIs. In java you'd have a bunch of private methods even though they are only ever used as subroutines inside of one method. – LuxuryMode Jul 04 '12 at 02:59
1
Dated, but what is the problem with the following?
def product_recursive(s: String): Long = {
if (s.length == 1)
s.head.toLong
else
s.head.toLong * product_recursive(s.tail)
}

Adam
- 284
- 3
- 7
-
Pretty much the same as the accepted answer except this one won't handle an empty string `""`. – jwvh Mar 03 '19 at 02:50