Scala partition a set - scala

I was looking at how to split a set in two based on the contents of a third set. Accidentally I stumbled upon this solution:
val s = Set(1,2,3)
val s2 = Set(4,5,6)
val s3 = s ++ s2
s3.partition(s)
res0: (scala.collection.immutable.Set[Int],scala.collection.immutable.Set[Int]) = (Set(1, 2, 3),Set(5, 6, 4))
The signature of partition is as follows:
def partition(p: A => Boolean): (Repr, Repr)
Can someone explain to me how providing a set instead of a function works?
Thanks in advance

A set s: Set[A] is a function A => Boolean: for any value a of A you return whether s contains a or not.
scala> val f: Int => Boolean = Set(1,2,3)
f: Int => Boolean = Set(1, 2, 3)
scala> f(1)
res0: Boolean = true
scala> f(4)
res1: Boolean = false
If you look a the documentation for .apply, you'll see
def apply(elem: A): Boolean
Tests if some element is contained in this set.
This method is equivalent to contains. It allows sets to be
interpreted as predicates.

Related

difference between following def and val partial functions

Is there a difference between whether I use def or val while defining a partial function? I thought that probably def will be evaluated everytime (like a function call) while val will be evaluated only once but that doesn't seem to be the case.
scala> def add(x:Int)(y:Int) = {println("inadd");x+y}
add: (x: Int)(y: Int)Int
//def
scala> def add2ToDef= add(2) _
add2ToDef: Int => Int
//val
scala> val add2ToVal= add(2) _
add2ToVal: Int => Int = $$Lambda$1032/1413020227#512abf25
scala> add2ToDef(3)
inadd
res0: Int = 5
scala> add2ToVal(3)
inadd
res1: Int = 5
scala> add2ToDef(4)
inadd
res2: Int = 6
scala> add2ToVal(5)
inadd
res3: Int = 7
Essentially the same difference as between val and def in general:
def will produce a new lambda (new object) every time you reference it.
val will produce it once (at definition time) and every reference to it refers to the same instance.
In this case, val makes more sense so it's not creating a new lambda every time.
You are right that:
def will be evaluated every time you reference the function and val will be evaluated only once and the same value will be used every time.
It is true with partial functions as well. To see the behavior you can see this example:
scala> def add(x:Int)(y:Int) = {println("inadd");x+y}
add: (x: Int)(y: Int)Int
scala> def addWithDef = add(2)(3)
addWithDef: Int
scala> addWithDef // Evaluated
inadd
res0: Int = 5
scala> addWithDef // Evaluated again as "inadd" is printed again
inadd
res1: Int = 5
scala> val addWithVal = add(2)(3) // Evaluated once
inadd
addWithVal: Int = 5
scala> addWithVal //Same value referenced again(no "inadd" printed)
res2: Int = 5
scala> addWithVal //Same value referenced again(no "inadd" printed)
res3: Int = 5

What does dot colon colon (.::) mean in Scala?

Below code adds element to res list. My question is how scala internally translates .:: symbols?
Code snippet:
var res = List[(Int, Int)]()
res .::= (1, 2)
res .::= (3, 4)
res
output:
res56: List[(Int, Int)] = List((1,2),(3,4))
There are a few things going on in that snippet. Before diving into it let's talk about the difference between var and val. Namely, that a variable declared using the val keyword is immutable, i.e. its value cannot be changed:
scala> val x = 1
x: Int = 1
scala> x = 2
<console>:13: error: reassignment to val
x = 2
^
On the other hand, var keyword is used to declare a mutable variable, i.e. its value can be changed:
scala> var y = "bar"
y: String = bar
scala> y = "foo"
y: String = foo
What if we wanted to compute a new value of y by appending to its current value?
scala> y = y + "bar"
y: String = foobar
Sure that works, but it turns out there's a shorthand for doing that:
scala> y += "bar"
scala> y
res10: String = foobar
By the way, in Scala, + is just a name of a method, so y + "bar" is the same as y.+("bar"). Ugly, but valid. Similarly, y.+=("bar") is also a valid replacement of y += "bar".
Great, let's remember that for later. Next, as others have already pointed out, :: is just a method for prepending elements to a list (from Java it can be invoked as someList.$colon$colon(someElement)). The important thing to note is that the :: method returns a new list:
scala> var letters = List("b", "c")
letters: List[String] = List(b, c)
scala> letters.::("a")
res1: List[String] = List(a, b, c)
scala> letters
res2: List[String] = List(b, c)
What if we wanted to set letters to the list which contains the letter "a"?
scala> letters = letters.::("a")
letters: List[String] = List(a, b, c)
Notice that this looks awfully similar to the previous example with strings. Does the shorthand work here too?
scala> letters ::= "a"
scala> letters
res6: List[String] = List(a, b, c)
Yes, it does. letters.::=("a") works as well.
Now, let's break down the original snippet:
Step 1
Create a variable named res and assign it an empty, immutable list. This empty list is intended to contain pairs of integers (Int, Int).
var res = List[(Int, Int)]()
Here's an alternative way of doing the same thing:
var res = List.empty[(Int, Int)]
(which, in my opinion, is a bit easier to read)
Step 2
Prepend a new element (1, 2) to list res and reassign the resulting list back to res.
res .::= (1, 2)
Or, without spaces:
res.::=(1, 2)
Looks familiar? We could've also written it out as:
res = res.::(1, 2)
Step 3
Prepend (3, 4) following the logic in step 2
Step 4
Print out current value of res, which should be: List((3,4), (1,2))
Side note
Confusingly, the compiler is lenient enough to allow us to specify only a single set of parentheses when calling ::, though we really ought to have two sets: one for the method invocation and another one for indicating a pair of integers. So, there happens to be yet another valid
way of writing the same thing res.::=((1, 2)).
More generally:
scala> def first(p:(Int, Int)):Int = p._1
first: (p: (Int, Int))Int
scala> first(6,7)
res0: Int = 6
scala> first((6,7))
res1: Int = 6
scala> first(6 -> 7) //lolz! another one using implicit conversion
res2: Int = 6
The implicit conversion is ever-present since it's defined in Predef.ArrowAssoc
mind = blown
I also recommend taking a look at What are all the instances of syntactic sugar in Scala?
Just method invocation
. (dot) used for method invocation on instance of a class.
:: is a method defined on the List
:: is a method declared in the List class which creates instance of scala.collection.immutable.:: class.
Notice that :: is a method in List class and also :: is a final class in the package scala.collection.immutable
Scala Standard library
Here is the implementation of the :: function in the List class
#SerialVersionUID(-6084104484083858598L) // value computed by serialver for 2.11.2, annotation added in 2.11.4
sealed abstract class List[+A] extends AbstractSeq[A]
with LinearSeq[A]
with Product
with GenericTraversableTemplate[A, List]
with LinearSeqOptimized[A, List[A]]
with Serializable {
override def companion: GenericCompanion[List] = List
import scala.collection.{Iterable, Traversable, Seq, IndexedSeq}
def isEmpty: Boolean
def head: A
def tail: List[A]
// New methods in List
/** Adds an element at the beginning of this list.
* #param x the element to prepend.
* #return a list which contains `x` as first element and
* which continues with this list.
*
* #usecase def ::(x: A): List[A]
* #inheritdoc
*
* Example:
* {{{1 :: List(2, 3) = List(2, 3).::(1) = List(1, 2, 3)}}}
*/
def ::[B >: A] (x: B): List[B] =
new scala.collection.immutable.::(x, this)
.....
}
Here is how scala.collection.immutable.:: is defined.
#SerialVersionUID(509929039250432923L) // value computed by serialver for 2.11.2, annotation added in 2.11.4
final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {
override def tail : List[B] = tl
override def isEmpty: Boolean = false
}
The output of
var res = List[(Int, Int)]()
res .::= (1, 2)
res .::= (3, 4)
res
should be
List((3,4), (1,2))
because the colon colon method :: adds an element to the front of a list.
The dot . is totally optional in this case - this is just for specifically stating, that you are calling method :: on the list object res. This means that your code is equivalent to this one:
var res = List[(Int, Int)]()
res ::= (1, 2)
res ::= (3, 4)
res
Internally colon colon :: is implemented like this:
/** Adds an element at the beginning of this list.
* #param x the element to prepend.
* #return a list which contains `x` as first element and
* which continues with this list.
*
* #usecase def ::(x: A): List[A]
* #inheritdoc
*
* Example:
* {{{1 :: List(2, 3) = List(2, 3).::(1) = List(1, 2, 3)}}}
*/
def ::[B >: A] (x: B): List[B] =
new scala.collection.immutable.::(x, this)
A new list is created (because of the immutability) with the argument as a first element and the current list content as the rest

Composing functions that return an option

Suppose I have a few functions of type Int => Option[Int]:
def foo(n: Int): Int => Option[Int] = {x => if (x == n) none else x.some}
val f0 = foo(0)
val f1 = foo(1)
I can compose them with >=> as follows:
val composed: Int => Option[Int] = Kleisli(f0) >=> Kleisli(f1)
Suppose now I need to compose all functions from a list:
val fs: List[Int => Option[Int]] = List(0, 1, 2).map(n => foo(n))
I can do it with map and reduce:
val composed: Int => Option[Int] = fs.map(f => Kleisli(f)).reduce(_ >=> _)
Can it (the composed above) be simplified ?
If you want the composition monoid (as opposed to the "run each and sum the results" monoid), you'll have to use the Endomorphic wrapper:
import scalaz._, Scalaz._
val composed = fs.foldMap(Endomorphic.endoKleisli[Option, Int])
And then:
scala> composed.run(10)
res11: Option[Int] = Some(10)
The monoid for kleisli arrows only requires a monoid instance for the output type, while the composition monoid requires the input and output types to be the same, so it makes sense that the latter is only available via a wrapper.
[A] Kleisli[Option, A, A] is a Semigroup via Compose, so we can use foldMap1:
val composed: Int => Option[Int] = fs.foldMap1(f => Kleisli(f))
Interestingly this doesn't work, though if we pass the correct instance explicitly then it does:
scala> val gs = NonEmptyList(fs.head, fs.tail: _*)
gs: scalaz.NonEmptyList[Int => Option[Int]] = NonEmptyList(<function1>, <function1>, <function1>)
scala> gs.foldMap1(f => Kleisli(f))(Kleisli.kleisliCompose[Option].semigroup[Int])
res20: scalaz.Kleisli[Option,Int,Int] = Kleisli(<function1>)
scala> gs.foldMap1(f => Kleisli(f))(Kleisli.kleisliCompose[Option].semigroup[Int]).apply(1)
res21: Option[Int] = None
I'm not sure where the instance that seems to take priority is coming from.

Meaning of type Set = Int => Boolean in Scala

I do not understand why Set defined in this way produces these results.
My understanding is that Set is just a function which takes an int and return boolean.
Can someone explain me why I get this result using set?
I think this is a short way to express the function in Scala but I am new to this language and I do not understand how it works.
object sets {
type Set = Int => Boolean
var a=Set(3) //> a : scala.collection.immutable.Set[Int] = Set(3)
a(2) //> res0: Boolean = false
a(3) //> res1: Boolean = true
a(1) //> res2: Boolean = false
}
The type you defined in type Set = Int => Boolean and the object you created in var a=Set(3) are actually not connected to each other. Even this works:
scala> type Set = String
defined type alias Set
scala> val a = Set(3)
a: scala.collection.immutable.Set[Int] = Set(3)
When you call Set(3), you call apply method on the object Set. If you add new keyword, it will take your type alias into account:
scala> val b = new Set()
b: String = ""
a(2), a(3), a(1) work because Set[A], actually, does implement A => Boolean function trait and apply method is equivalent to contains: http://www.scala-lang.org/api/2.10.3/index.html#scala.collection.immutable.Set
I agree what izstas said they are different things. But "type Set = Int => Boolean" has effect. In the following steps in scala console, after "type Set = Int => Boolean" the error disappears.
scala> def func(s:Set) = 1
<console>:10: error: type Set takes type parameters
def func(s:Set) = 1
^
scala> def func(s:Set[Int]) = 1
func: (s: Set[Int])Int <---- specify the type in the set
scala> type Set = Int => Boolean
defined type alias Set
scala> def func(s:Set) = 1 <---- no error
func: (s: Set)Int
scala> def getSet(s:Set) = s
getSet: (s: Set)Set
scala> getSet(Set(1,2))
res0: Set = Set(1, 2)
scala> Set(1,2)
res1: scala.collection.immutable.Set[Int] = Set(1, 2)
scala> val t=Set(1,2)
t: scala.collection.immutable.Set[Int] = Set(1, 2)

Is there a way to create transform two equivalent types in Scala reflection into two equal types?

Consider the following:
scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._
scala> typeOf[Boolean]
res23: reflect.runtime.universe.Type = Boolean
scala> typeOf[scala.Boolean]
res24: reflect.runtime.universe.Type = Boolean
scala> res23 == res24
res25: Boolean = true
scala> typeOf[java.lang.Boolean]
res26: reflect.runtime.universe.Type = Boolean
scala> res23 == res26
res27: Boolean = false
scala> class Foo { def bf(arg: Boolean) = ??? }
defined class Foo
scala> typeOf[Foo]
res28: reflect.runtime.universe.Type = Foo
scala> res28.member(newTermName("bf")).asMethod
res30: reflect.runtime.universe.MethodSymbol = method bf
scala> res30.paramss.head.head
res31: reflect.runtime.universe.Symbol = value arg
scala> res31.typeSignature
res32: reflect.runtime.universe.Type = scala.Boolean
scala> res32 == res23
res33: Boolean = false
scala> res32 =:= res23
res37: Boolean = true
So the type obtained via the typeOf[Boolean] function is equivalent to the type obtained via inspecting a method, but it is not equal.
Is there a way to transform two equivalent types into some canonical representation where the results will be equal? I'd like to be able to use them for things like keys in maps.
Edit:
To be more clear, what I'm looking for is something along the lines of (not a real repl session):
scala>val tp1 = // some type
scala>val tp2 = // equivalent type obtained another way
scala>tp1 == tp2
res1: Boolean = false
scala>tp1 =:= tp2
res2: Boolean = true
scala>val ctp1 = tp1.canonical
scala>val ctp2 = tp2.canonical
scala>ctp1 == ctp2
res3: Boolean = true
scala>ctp1 =:= tp1
res4: Boolean = true
scala>ctp2 =:= tp2
res5: Boolean = true
So equivalence is preserved by the transformation. I also need it to work on parameterized types.
From the documentation:
It's important to note that == should not be used to compare types for
equality—== can't check for type equality in the presence of type
aliases, while =:= can.
You can of course store the types in a list and use (for example) the following to check for inclusion:
myTypes.exists(_ =:= someType)
You'll see this approach in the 2.10 compiler source, for example. It's not as efficient as a map or set, of course, but you generally don't have many of these things in a collection.
If you absolutely have to have the performance of a map or set, you may be able to use erasure (as another answer suggests) or typeSymbol, depending on your requirements.
erasure method of scala.reflect.api.Types.TypeApi:
typeOf[Foo].member(newTermName("bf")).asMethod.paramss.head.head
.typeSignature.erasure == typeOf[Boolean]
// res21: Boolean = true