Reputation: 321
I'm trying to write a function that returns a set of integers, when I specify it to as a parameter.
I know that in scala, the trait Set[A]
extends (A => Boolean)
, so I tried something like the below:
def foo(x: Int): Set[Int] = {
return {(y: Int) => y match
case x => true
case _ => false
}
}
But doesn't work, returning
found : A => Boolean
required: Set[A]
Since it isn't in the form it wants, I assume. How can I change my code so it returns a valid set?
Upvotes: 0
Views: 71
Reputation: 1551
Why not just return a set instance? like this:
Welcome to Scala 2.13.1 (OpenJDK 64-Bit Server VM, Java 1.8.0_222).
Type in expressions for evaluation. Or try :help.
scala> def set(x: Int): Set[Int] = Set(x)
set: (x: Int)Set[Int]
scala> val s = set(1)
s: Set[Int] = Set(1)
scala> s(1)
res0: Boolean = true
scala> s(2)
res1: Boolean = false
Upvotes: 0
Reputation: 27535
Well, Set[A]
is a function A => Boolean
, true. But it is also a collection that can be traversed, filtered, mapped, etc. You can create something as a function and let the compiler turn it into an object... but only when the type you are implementing that way is single abstract method.
Meanwhile, Set[A]
in Scala 2.13 has, well, quite a lot of methods to implement.
def size: Int
def isEmpty: boolean
def knownSize: Int
def filter(pred: A => Boolean): Set[A]
def filterNot(pred: A => Boolean): Set[AnyA
def removedAll(that: IterableOnce[A]): Set[A]
def diff(that: collection.Set[A]): Set[A]
def subsetOf(that: collection.Set[A]): Boolean
def intersect(that: collection.Set[A]): Set[A]
def view: View[A]
def contains(elem: A): Boolean
def incl(elem: A): Set[A]
def excl(elem: A): Set[A]
def iterator: Iterator[A]
def foreach[U](f: A => U): Unit
and how would you create that Set[Int]
... would you iterate over all possible Int
s? You could make that lazily, but the moment someone called iterator
, foreach
, etc you would have to materialize these values.
For that reason it is rather unlikely that you will ever use full implementation of Set[Int]
materialized from a function Int => Boolean
. At best you could implement your own Set
implementation that provides only some fraction of the Set
interface that doesn't require iterating over whole Int
type.
The opposite is trivial though. set.apply(int)
is what you are able to do because Set[Int]
extends Int => Boolean
, so you can assign Set[Int]
as a Int => Boolean
function.
Upvotes: 2
Reputation: 48410
Set[A]
is a subtype of A => Boolean
, not the other way around
implicitly[Set[Int] <:< (Int => Boolean)] // OK
implicitly[(Int => Boolean) <:< Set[Int]] // ERROR
so the following is valid
val s: Int => Boolean = Set(1,2,3)
s(4)
// res0: Boolean = false
but not
val s: Set[Int] = (x: Int) => true // Error: type mismatch
Upvotes: 2