This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Why can't Scala figure out the types on this method?

3 replies
Mitchell Hashimoto
Joined: 2011-03-27,
User offline. Last seen 42 years 45 weeks ago.

Hello,

So I'm going through the "Why Functional Programming Matters" paper by
Hughes (1990 revision), and for fun I've been putting all the examples
into Scala. However, I can't quite figure out why the following gives
an error (which is below the code sample).

I realize that this method would make more sense on the class itself,
but for first-pass purposes I'm just translating the code in the paper
almost as closely as possible to Scala.

If you prefer syntax highlighted version:
https://gist.github.com/d8c8f44fe6c510934e6c

// page 7
sealed abstract class Treeof[+X]
final case class Node[X](val label: X, val subtrees: Listof[Node[X]])
extends Treeof[X]

def foldtree[X,A](f: (X, A) => A, g: (A,A) => A, a: A, tree: Node[X]): A =
f(tree.label, foldtree(f, g, a, tree.subtrees))
def foldtree[X,A](f: (X, A) => A, g: (A,A) => A, a: A, subtrees:
Listof[Node[X]]): A =
subtrees match {
case Nil => a
case Cons(subtree, rest) =>
g(foldtree(f, g, a, subtree), foldtree(f, g, a, rest))
}

// page 8
def sumtree[Int](tree: Node[Int]): Int =
foldtree[Int,Int](_ + _, _ + _, 0, tree)

And the error given:

/Users/mitchellh/Desktop/scala/test.scala:45: error: missing parameter
type for expanded function ((x$4, x$5) => x$4.$plus(x$5))
foldtree[Int,Int](_ + _, _ + _, 0, tree)
^
/Users/mitchellh/Desktop/scala/test.scala:45: error: missing parameter
type for expanded function ((x$4: , x$5) => x$4.$plus(x$5))
foldtree[Int,Int](_ + _, _ + _, 0, tree)
^
/Users/mitchellh/Desktop/scala/test.scala:45: error: missing parameter
type for expanded function ((x$6, x$7) => x$6.$plus(x$7))
foldtree[Int,Int](_ + _, _ + _, 0, tree)
^
/Users/mitchellh/Desktop/scala/test.scala:45: error: missing parameter
type for expanded function ((x$6: , x$7) => x$6.$plus(x$7))
foldtree[Int,Int](_ + _, _ + _, 0, tree)
^
/Users/mitchellh/Desktop/scala/test.scala:45: error: overloaded method
value foldtree with alternatives:
(f: (Int(in method sumtree), Int(in method sumtree)) => Int(in
method sumtree),g: (Int(in method sumtree), Int(in method sumtree)) =>
Int(in method sumtree),a: Int(in method sumtree),subtrees:
this.Listof[this.Node[Int(in method sumtree)]])Int(in method sumtree)

(f: (Int(in method sumtree), Int(in method sumtree)) => Int(in
method sumtree),g: (Int(in method sumtree), Int(in method sumtree)) =>
Int(in method sumtree),a: Int(in method sumtree),tree:
this.Node[Int(in method sumtree)])Int(in method sumtree)
cannot be applied to ((, ) => , (,
) => , scala.Int, this.Node[Int(in method sumtree)])
foldtree[Int,Int](_ + _, _ + _, 0, tree)
^
5 errors found

Note that line 45 is the `sumtree` method body.

Thanks,
Mitchell

Derek Williams
Joined: 2009-06-13,
User offline. Last seen 42 years 45 weeks ago.
Re: Why can't Scala figure out the types on this method?

On Tue, Mar 29, 2011 at 4:39 PM, Mitchell Hashimoto
wrote:
> // page 8
> def sumtree[Int](tree: Node[Int]): Int =
> foldtree[Int,Int](_ + _, _ + _, 0, tree)

It doesn't fix the type inference, but you have a mistake here. You
are shadowing Int, so it doesn't mean what you think it means here.
Change that to

def sumtree(tree: Node[Int]): Int =
foldtree[Int,Int](_ + _, _ + _, 0, tree)

Derek Williams
Joined: 2009-06-13,
User offline. Last seen 42 years 45 weeks ago.
Re: Why can't Scala figure out the types on this method?

On Tue, Mar 29, 2011 at 4:39 PM, Mitchell Hashimoto
wrote:
> Hello,
>
> So I'm going through the "Why Functional Programming Matters" paper by
> Hughes (1990 revision), and for fun I've been putting all the examples
> into Scala. However, I can't quite figure out why the following gives
> an error (which is below the code sample).

I'm not 100% sure why type inference is failing here, but I've always
had good luck moving functions into separate parameter lists for stuff
like this. This compiles (note I am using Scala's List here as it
wouldn't compile):

// page 7
sealed abstract class Treeof[+X]
final case class Node[X](val label: X, val subtrees: List[Node[X]])
extends Treeof[X]

// page 7 take 1
def foldtree[X,A](a: A, tree: Node[X])(f: (X, A) => A)(g: (A,A) => A): A =
f(tree.label, foldtree(a, tree.subtrees)(f)(g))
def foldtree[X,A](a: A, subtrees: List[Node[X]])(f: (X, A) => A)(g:
(A,A) => A): A =
subtrees match {
case Nil => a
case subtree :: rest =>
g(foldtree(a, subtree)(f)(g), foldtree(a, rest)(f)(g))
}

// page 8
def sumtree(tree: Node[Int]): Int =
foldtree(0, tree)(_ + _)(_ + _)

Mitchell Hashimoto
Joined: 2011-03-27,
User offline. Last seen 42 years 45 weeks ago.
Re: Why can't Scala figure out the types on this method?

Derek,

On Tue, Mar 29, 2011 at 4:20 PM, Derek Williams wrote:
> On Tue, Mar 29, 2011 at 4:39 PM, Mitchell Hashimoto
> wrote:
>> Hello,
>>
>> So I'm going through the "Why Functional Programming Matters" paper by
>> Hughes (1990 revision), and for fun I've been putting all the examples
>> into Scala. However, I can't quite figure out why the following gives
>> an error (which is below the code sample).
>
> I'm not 100% sure why type inference is failing here, but I've always
> had good luck moving functions into separate parameter lists for stuff
> like this. This compiles (note I am using Scala's List here as it
> wouldn't compile):

Oh yeah, sorry about the Listof, its just a cons list just like
Scala's builtin :) But very basic.

And thanks for at least getting this to compile. Like you said, I'm
not 100% sure why this is failing, and wasn't sure if this was some
sort of Scala compiler bug?

Best,
Mitchell

>
> // page 7
> sealed abstract class Treeof[+X]
> final case class Node[X](val label: X, val subtrees: List[Node[X]])
> extends Treeof[X]
>
> // page 7 take 1
> def foldtree[X,A](a: A, tree: Node[X])(f: (X, A) => A)(g: (A,A) => A): A =
>  f(tree.label, foldtree(a, tree.subtrees)(f)(g))
> def foldtree[X,A](a: A, subtrees: List[Node[X]])(f: (X, A) => A)(g:
> (A,A) => A): A =
>  subtrees match {
>    case Nil => a
>    case subtree :: rest =>
>      g(foldtree(a, subtree)(f)(g), foldtree(a, rest)(f)(g))
>  }
>
> // page 8
> def sumtree(tree: Node[Int]): Int =
>  foldtree(0, tree)(_ + _)(_ + _)
>
>
>
> --
> Derek
>

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland