0

Im new to learning scala, and working thorough the book Functional Programming in Scala. I'm having some conceptual and programming issues working out how to test my solutions to exercises, which relate to how to properly call methods defined in companion object.

I have the following data type MyList that I have defined following along with the book

sealed trait MyList[+A]
case object Nil extends MyList[Nothing]
case class Cons[+A](head: A, tail: MyList[A]) extends MyList[A]

object MyList {

    def apply[A](as: A*): MyList[A] = {
        if (as.isEmpty) Nil
        else Cons(as.head, apply(as.tail: _*))
    }

    def sum(ints: MyList[Int]): Int = ints match {
        case Nil => 0
        case Cons(x, xs) => x + sum(xs)
    }

    def product(ds: MyList[Double]): Double = ds match {
        case Nil => 1
        case Cons(x, xs) => x * product(xs)
    }

}

I would like to test my implementation of the methods apply, sum and product in the companion object. To this end, I have added the following lines (these ones work) to the file after the object definition

val x = MyList(1, 2, 3, 4)
println(x)

If I run these (I'm a command line type person, so this is though a bash shell session) it seems to work as I would expect

$ scala ch3-list.scala
Cons(1,Cons(2,Cons(3,Cons(4,Nil))))

But I'm having trouble with the other two functions. Ive tried the following combinations

println(x.sum())
println(sum(x))
println(x.sum(x))
println(x.sum)

and they all give me errors. For example, x.sum(), which I thought was most likely to work, gives

$ scala ch3-list.scala
/Users/matthewdrury/Projects/fp-in-scala/ch3-list.scala:28: error: value sum is not a member of this.MyList[Int]
println(x.sum())
          ^

I'm new to scala, and have no java experience either, so the scoping rules are still fuzzy to me. I'd like to know what I'm missing here conceptually, and get some advice on the best workflow to setup to test further methods of this kind.

Matthew Drury
  • 845
  • 8
  • 17

1 Answers1

2

You're looking for MyList.sum(x).

The sum method is in the companion object, not defined as a member of the MyList class.

Jean-Philippe Pellet
  • 59,296
  • 21
  • 173
  • 234
  • I really should have thought of that : ) Is there a generally better way to go about setting this up? – Matthew Drury Mar 18 '16 at 22:50
  • Make them member methods of `MyList` and and switch on `this`. However, you will run into more complicated matters as inside `MyList` you don't know what `A` is (`Int`, `Double`, some other not addable/multipliable class…). You can solve this with [generalized type constraints](http://stackoverflow.com/q/3427345/390581). – Jean-Philippe Pellet Mar 18 '16 at 22:52