- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Why can't Scala figure out the types on this method?
Tue, 2011-03-29, 23:39
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
Wed, 2011-03-30, 00:27
#2
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)(_ + _)(_ + _)
Wed, 2011-03-30, 00:37
#3
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
>
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)