Here's my code:
object Triple {
object Num extends Enumeration {
type Num = Value
val one, two, three, four, five, six, seven, eight, nine = Value
}
val triples = for {
first <- Num.values
second <- Num.values
third <- Num.values
if (first != second)
if (first != third)
if (second != third)
} yield Set(first, second, third)
}
I get an error on the line with third. It says:
Multiple markers at this line
- not enough arguments for method map: (implicit bf:
scala.collection.generic.CanBuildFrom[sudoku.Triple.Num.ValueSet,scala.collection.immutable.Se t[sudoku.Triple.Num.Value],That])That. Unspecified
value parameter bf.
- diverging implicit expansion for type
scala.collection.generic.CanBuildFrom[sudoku.Triple.Num.ValueSet,scala.collection.immutable.Set[sudoku.Triple.Num.Value],That] starting with
method newCanBuildFrom in object SortedSet
- not enough arguments for method map: (implicit bf:
scala.collection.generic.CanBuildFrom[sudoku.Triple.Num.ValueSet,scala.collection.immutable.Set[sudoku.Triple.Num.Value],That])That. Unspecified
value parameter bf.
- diverging implicit expansion for type
scala.collection.generic.CanBuildFrom[sudoku.Triple.Num.ValueSet,scala.collection.immutable.Set[sudoku.Triple.Num.Value],That] starting with
method newCanBuildFrom in object SortedSet
Update: Aleksey Izmailov gave a great answer. A slightly better implementation of the function is val triples=Num.values.subset(3).toSet
Looks like what you are trying to do is this:
scala> object Num extends Enumeration {
| type Num = Value
| val one, two, three, four, five, six, seven, eight, nine = Value
| }
defined module Num
scala> val triples = Num.values.toList.combinations(3)
triples: Iterator[List[Num.Value]] = non-empty iterator
scala> triples.toList
res0: List[List[Num.Value]] = List(List(one, two, three), List(one, two, four), List(one, two, five), List(one, two, six), List(one, two, seven), List(one, two, eight), List(one, two, nine), List(one, three, four), List(one, three, five), List(one, three, six), List(one, three, seven), List(one, three, eight), List(one, three, nine), List(one, four, five), List(one, four, six), List(one, four, seven), List(one, four, eight), List(one, four, nine), List(one, five, six), List(one, five, seven), List(one, five, eight), List(one, five, nine), List(one, six, seven), List(one, six, eight), List(one, six, nine), List(one, seven, eight), List(one, seven, nine), List(one, eight, nine), List(two, three, four), List(two, three, five), List(two, three, six), List(two, three, seven), List(two, three...
scala>
If you do something like this then it works:
scala> object Triple {
| object Num extends Enumeration {
| type Num = Value
| val one, two, three, four, five, six, seven, eight, nine = Value
| }
| val triples = for {
| first <- Num.values
| second <- Num.values
| third <- Num.values
| if (first != second)
| if (first != third)
| if (second != third)
| } yield (first, second, third)
| }
defined module Triple
scala> Triple.triples
res1: scala.collection.immutable.SortedSet[(Triple.Num.Value, Triple.Num.Value, Triple.Num.Value)] = TreeSet((one,two,three), (one,two,four), (one,two,five), (one,two,six), (one,two,seven), (one,two,eight), (one,two,nine), (one,three,two), (one,three,four), (one,three,five), (one,three,six), (one,three,seven), (one,three,eight), (one,three,nine), (one,four,two), (one,four,three), (one,four,five), (one,four,six), (one,four,seven), (one,four,eight), (one,four,nine), (one,five,two), (one,five,three), (one,five,four), (one,five,six), (one,five,seven), (one,five,eight), (one,five,nine), (one,six,two), (one,six,three), (one,six,four), (one,six,five), (one,six,seven), (one,six,eight), (one,six,nine), (one,seven,two), (one,seven,three), (one,seven,four), (one,seven,five), (one,seven,six), (one,...
scala>
Note the result of the produced collection is a SortedSet
. That result is defined by Num.values
- you can convert for
comprehension to map
, flatMap
and filter
to check how the types come about.
The problem is that you can put stuff that can be sorted into SortedSet
like this for example:
scala> scala.collection.immutable.SortedSet(1, 2)
res6: scala.collection.immutable.SortedSet[Int] = TreeSet(1, 2)
However, you can't put something that does not have ordering defined into a SortedSet
because SortedSet
guarantees that the stuff is sorted and should know how sorting is done (via implicit ordering):
scala> scala.collection.immutable.SortedSet(Set(1, 2), Set(3, 4))
<console>:8: error: No implicit Ordering defined for scala.collection.immutable.Set[Int].
scala.collection.immutable.SortedSet(Set(1, 2), Set(3, 4))
Scala looks for implicit Ordering
to be defined in scope and does not find one for the Set
that you are using, or for the Set[Int]
in my example.
Now let's "fix" it:
scala> implicit val dummyOrdering: Ordering[Set[Int]] = Ordering.by(_.size)
dummyOrdering: Ordering[Set[Int]] = scala.math.Ordering$$anon$9@6f00d9a7
scala> scala.collection.immutable.SortedSet(Set(1, 2), Set(3, 4))
res8: scala.collection.immutable.SortedSet[scala.collection.immutable.Set[Int]] = TreeSet(Set(3, 4))
Obviously, this is a bad fix and the real problem is that in your case types are not well chosen. First of all you don't need to use a Set
for each combination since you already comparing things to avoid repetition. Just use a Tuple3
. Second, if you insist on using a Set
, then convert Num.values
to List
in the for
comprehension:
scala> object Triple {
| object Num extends Enumeration {
| type Num = Value
| val one, two, three, four, five, six, seven, eight, nine = Value
| }
| val triples = for {
| first <- Num.values.toList
| second <- Num.values.toList
| third <- Num.values.toList
| if (first != second)
| if (first != third)
| if (second != third)
| } yield Set(first, second, third)
| }
defined module Triple
Hope that makes it clear. Basically the problem is in the choice of wrong types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With