0

I have two solutions, but one doesn't compile and the other, I think, could be better:

object Foo extends App {
     val vectors = List(List(1,2,3), List(2,2,3), List(1,2,2)) //just a stupid example

     //transposing
     println("vectors = " + vectors.transpose.map (_.sum)) //it prints vectors = List(4, 6, 8)

     //folding
     vectors.reduce {
        case (a, b) => (a zip b) map {
           case (x, y) => x + y
        }
     } //compiler says: missing parameter type for exp. function; arg. types must be fully known
} 

2 Answers2

5

reduce accepts a Function2 argument, but you've given it a PartialFunction.

vectors reduce { (a, b) => (a zip b) map { case (x, y) => x+y } }

Edit: My code works, but @sschaef pointed out that my explanation was wrong: davips's code doesn't compile due to limitations in type inference. See Type inference fails on Set made with .toSet?

Community
  • 1
  • 1
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
  • 2
    Not a `PartialFunction`, he just used Pattern Matching. – kiritsuku Nov 08 '13 at 08:13
  • A block with `case` clauses, used without `match`, is a `PartialFunction`, isn't it? For example, type this into the REPL: { case "a" => true }: PartialFunction[String, Boolean] – Chris Martin Nov 09 '13 at 01:55
  • No it is not, it is a normal function. Just when you tell the compiler that you want a partial function you will get one. Example: `List(1, "str") map {case s: String => s } ==> MatchError` – kiritsuku Nov 09 '13 at 10:26
  • A `PartialFunction` *is* a "normal function", in that it extends `Function1`. In your example, you get a `MatchError`; how does that lead you to infer that the compiler didn't create a `PartialFunction` there? – Chris Martin Nov 09 '13 at 17:01
  • Because it is [speced](http://iainmcgin.github.io/scala-ref-markdown/ScalaReferenceWebTeX.html#pattern-matching-anonymous-functions) that way. – kiritsuku Nov 09 '13 at 19:30
  • Well, reading that, now I'm confused about why davips's snippet doesn't compile. Shouldn't that pattern match block expand into a `Function2` according to the first substitution rule in that section of the spec? – Chris Martin Nov 09 '13 at 20:24
  • type inference limitation, `vectors.reduce[Type](f)` will work (`reduce` has a lower bound type parameter). See [this question](http://stackoverflow.com/questions/5544536/type-inference-on-set-failing) for more information. – kiritsuku Nov 09 '13 at 21:26
  • Can it be called a syntax corner case? I mean, is it expected from the programmer to delve into such details about what is really going on or I am missing something? –  Nov 14 '13 at 06:05
1
val vectors = List(List(1,2,3), List(2,2,3), List(1,2,2))

implicit class VectorizedOps[T : Numeric](vec: List[T]) {
  private val numeric = implicitly[Numeric[T]]
  def +(other: List[T]) = (vec zip other).map { case (x, y) => numeric.plus(x, y) }
}

val sum = vectors.reduce( _ + _ )

Maybe not faster but more idiomatic

alkersan
  • 3,419
  • 3
  • 19
  • 23