Just like Stream is a lazy Seq, is there a lazy version of Map?
What I want to do:
val lm = LazyMap[Int, String]((a) => {
println("only once")
(a * a).toString()
})
lm.get(10) // print "only once"
lm.get(10) // print nothing
You are basically asking for a cache.
You might have a shot at using scalaz.Memo, which adds memoization to a given function.
See http://eed3si9n.com/learning-scalaz/Memo.html
This would give something like:
val lm: Int => String = Memo.mutableHashMapMemo[Int, String] { a =>
println("only once")
(a * a).toString()
}
Note however that what you get is a function, not a map. This means that you cannot test for the presence or absence of a given key, you can only apply.
But if I am to trust your example, in your case this is exactly what you want.
mutable.Map provides the method getOrElseUpdate(key: A, op: ⇒ B): B. You could use that to implement lazy semantics.
You should wrap the class in another class though, because else the value can be changed later by anyone who has the reference to that map.
Related
I have a Future of Tuple like this Future[(WriteResult, MyObject)] mytuplefuture, I'd like to map it and do something with MyObject so I am doing this:
mytuplefuture.map((wr,obj)=>{ //do sth});
but my eclipse scala IDE does not allow and recommend me to do:
mytuplefuture.map{ case(wr,obj) => { //do sth }}
what is the difference between those two?
I am used to doing the first one, I do not know about the second one until I try returning that tuple that wrapped in a future
myfuture.map((obj) => { // do sth with obj })
it was clear, I am mapping the content of the Future and do something with it, which will return another future because the original myfuture only contains something (obj) in the future..
Would anyone explain please?
The difference is this:
map is a higher-order function (HOF) that takes a function as its argument. This function - let's call it the mapping function for convenience - itself takes a single argument, which is the value of the completed Future. In this particular case, this value happens to be a tuple. Your first attempt assumed that the tuple could be broken open into two arguments, which would then be accepted by the mapping function - but that's not going to happen, hence the error.
It might seem that you could define the mapping function like this (note the extra parentheses around the arguments):
mytuplefuture.map(((wr,obj)) => /* do sth */)
however this is not currently supported by the Scala compiler. (That said, I think this might be a feature of a future Scala release.)
So, the alternative is to write the mapping function as a partial function using the case statement. The following:
mytuplefuture.map {
case (wr,obj) => //
}
is actually a kind of shorthand for:
mytuplefuture.map {
tuple: (WriteResult, MyObject) => tuple match {
case (wr,obj) => // do sth
}
}
In fact, this shorthand is generally useful for situations other than just breaking open tuples. For instance:
myList.filter {
case A => true
case _ => false
}
is short for:
myList.filter {
x => x match {
case A => true
case _ => false
}
}
So, let's say you wish to look at just the MyObject member of the tuple. You would define this as follows:
val myfuture = mytuplefuture.map {
case (_, obj) => obj
}
or, alternatively, being explicit with the tuple argument:
val myfuture = mytuplefuture.map(tuple => tuple._2)
which can in turn be simplified to just:
val myfuture = mytuplefuture.map(_._2)
where the first underscore is shorthand for the first argument to the mapping function. (The second underscore, as in _2, is part of the name for the second value in the tuple, and is not shorthand - this is where Scala can get a little confusing.)
All of the previous three examples return a Future[MyObject].
If you then apply map to this value, the single mapping function argument in this case will be your MyObject instance. Hence you can now write:
myfuture.map(obj => /* Do something with obj */)
As to the remainder of your question, the mapping function as applied to a Future's value does indeed apply to the result of the original future, since it can't be executed until the first future has completed. Therefore, map returns a future that completes (successfully or otherwise) when the first future completes.
UPDATED: Clarified what the argument to map actually is. Thanks to #AlexeyRomanov for putting me right, and to #RhysBradbury for pointing out my initial error. ;-)
The difference is, that case indicates decomposition (or extraction) of the object (invoking unapply, which you can implement yourself).
myfuture.map(obj => obj._2 ) in this case obj - is your tuple, so you can access its elements by ._1 and ._2
mytuplefuture.map{ case(wr,obj) => { //do sth }} this decompose tuple to its elements.
You can better feel the difference, by using this approach on case class which comes with a default unapply implementation
case class MyClass(int: Int)
List(MyClass(1)) map { myclass => myclass.int } // accesing the elements
List(MyClass(1)) map { case MyClass(i) => i + 1 } // decomposition
In your case I'd write
mytuplefuture.map(_.2).map( // do somthing )
P.S.
You can do the extraction for many other classes (Option for example).
It is also allowing you to write something like
val (a, b) = tuple
val MyClass(x) = myclass
I have a variable underlying of type Option[mutable.Traversable[Field]]
All I wanted todo in my class was provide a method to return this as Sequence in the following way:
def toSeq: scala.collection.mutable.Seq[Field] = {
for {
f <- underlying.get
} yield f
}
This fails as it complains that mutable.traversable does not conform to mutable.seq. All it is doing is yielding something of type Field - in my mind this should work?
A possible solution to this is:
def toSeq: Seq[Field] = {
underlying match {
case Some(x) => x.toSeq
case None =>
}
}
Although I have no idea what is actually happening when x.toSeq is called and I imagine there is more memory being used here that actually required to accomplish this.
An explanation or suggestion would be much appreciated.
I am confused why you say that "I imagine there is more memory being used here than actually required to accomplish". Scala will not copy your Field values when doing x.toSeq, it is simply going to create an new Seq which will have pointers to the same Field values that underlying is pointing to. Since this new structure is exactly what you want there is no avoiding the additional memory associated with the extra pointers (but the amount of additional memory should be small). For a more in-depth discussion see the wiki on persistent data structures.
Regarding your possible solution, it could be slightly modified to get the result you're expecting:
def toSeq : Seq[Field] =
underlying
.map(_.toSeq)
.getOrElse(Seq.empty[Field])
This solution will return an empty Seq if underlying is a None which is safer than your original attempt which uses get. I say it's "safer" because get throws a NoSuchElementException if the Option is a None whereas my toSeq can never fail to return a valid value.
Functional Approach
As a side note: when I first started programming in scala I would write many functions of the form:
def formatSeq(seq : Seq[String]) : Seq[String] =
seq map (_.toUpperCase)
This is less functional because you are expecting a particular collection type, e.g. formatSeq won't work on a Future.
I have found that a better approach is to write:
def formatStr(str : String) = str.toUpperCase
Or my preferred coding style:
val formatStr = (_ : String).toUpperCase
Then the user of your function can apply formatStr in any fashion they want and you don't have to worry about all of the collection casting:
val fut : Future[String] = ???
val formatFut = fut map formatStr
val opt : Option[String] = ???
val formatOpt = opt map formatStr
I'm implementing a class to constrain the access on an iterable. Intermediate steps of the sequence (after some map, etc...) is expected to be too big for memory. Thus map (and the likes: scanLeft, reduce, ...) should be lazy.
Internally I use map(...) = iterable.view.map( ... ). But it seems, IterableView.view is not it-self, which produce useless redirection when calling map multiple times. It is probably not critical, but I'd like to call .view only if the iterable is not already a view.
So, how can I case-match a View?
class LazyIterable[A](iterable: Iterable[A]){
def map[B](f: A => B) = {
val mapped = iterable match {
case v: View[A] => v // what should be here?
case i: Iterable[A] => i.view
}.map( f ))
new LazyIterable(mapped)
}
def compute() = iterable.toList
}
Note that I don't know what is the inputed Iterable, a concrete Seq (e.g. List, Vector) or a View. And if a View, I don't know on which concrete seq type (e.g. InterableView, SeqView, ...). And I got lost in the class hierarchy of View's & ViewLike's.
v: IterableView[A,_] is probably what you are looking for ...
But I don't think you need any of this to begin with.
I simply don't see what having this wrapper buys you at all. What benefits does writing
new LazyIterable(myThing).map(myFunc).compute
have over
myThing.view.map(myFunc).toList
Okay, I guess question is already complete in the title.
Nothing big, but I am just wondering. I have a method which returns either a correct value or an error code enum item. For example something like this:
def doMyStuff(): Future[_] = {
val result = db.queryMyData().map {
case some(data) =>
val modifiedData = data.doStuff()
modifiedData
case None =>
Errors.THIS_IS_FALSE
}
result
}
Where db.queryMyData() returns a Future, and data.doStuff() just modifies the data.
Now I have intuitively written Future[_], cause the return value is flexible. But when looking in other libraries I've seen Future[Any] used. Which seems to be logic too, when you use a match-case on the return of the function to check which data it is.
The code which uses that is for example something like this:
doMyStuff().map {
case data: MyDataType => // Blah blah
case Errors.Value => // error handling
}
So, my questions is: What's the difference between the use of Any or _ here, and why should I use the correct one?
It is a matter of semantics:
The Existential TypeT[_] means there is a class/type at the position of _ for which I do not care at all but it must be there.
T[Any] means there has to be a subclass Any present.
The difference comes into play when you want to serialize the underlying class.
If you just use _ without any typebounds you will not be able to use some of the many Scala JSON libraries.
I'm trying to get a better understanding of the correct usage of apply and unapply methods.
Considering an object that we want to serialize and deserialize, is this a correct usage (i.e. the Scala way) of using apply and unapply?
case class Foo
object Foo {
apply(json: JValue): Foo = json.extract[Foo]
unapply(f: Foo): JValue = //process to json
}
Firstly, apply and unapply are not necessarily opposites of each other. Indeed, if you define one on a class/object, you don't have to define the other.
apply
apply is probably the easier to explain. Essentially, when you treat your object like a function, apply is the method that is called, so, Scala turns:
obj(a, b, c) to obj.apply(a, b, c).
unapply
unapply is a bit more complicated. It is used in Scala's pattern matching mechanism and its most common use I've seen is in Extractor Objects.
For example, here's a toy extractor object:
object Foo {
def unapply(x : Int) : Option[String] =
if(x == 0) Some("Hello, World") else None
}
So now, if you use this is in a pattern match like so:
myInt match {
case Foo(str) => println(str)
}
Let's suppose myInt = 0. Then what happens? In this case Foo.unapply(0) gets called, and as you can see, will return Some("Hello, World"). The contents of the Option will get assigned to str so in the end, the above pattern match will print out "Hello, world".
But what if myInt = 1? Then Foo.unapply(1) returns None so the corresponding expression for that pattern does not get called.
In the case of assignments, like val Foo(str) = x this is syntactic sugar for:
val str : String = Foo.unapply(x) match {
case Some(s) => s
case None => throw new scala.MatchError(x)
}
The apply method is like a constructor which takes arguments and creates an object, whereas the unapply takes an object and tries to give back the arguments.
A simple example:
object Foo {
def apply(name: String, suffix: String) = name + "." + suffix
def unapply(name: String): Option[(String, String)] = {
//simple argument extractor
val parts = name.split("\\.")
if (parts.length == 2) Some(parts(0), parts(1)) else None
}
}
when you call
val file = Foo("test", "txt")
It actually calls Foo.apply("test", "txt") and returns test.txt
If you want to deconstruct, call
val Foo(name) = file
This essentially invokes val name = Foo.unapply(file).get and returns (test, txt) (normally use pattern matching instead)
You can also directly unpack the tuple with 2 variables, i.e.
scala> val Foo(name, suffix) = file
val name: String = test
val suffix: String = txt
BTW, the return type of unapply is Option by convention.
So apply and unapply are just defs that have extra syntax support.
Apply takes arguments and by convention will return a value related to the object's name. If we take Scala's case classes as "correct" usage then the object Foo's apply will construct a Foo instance without needing to add "new". You are free of course to make apply do whatever you wish (key to value in Map, set contains value in Set, and indexing in Seq come to mind).
Unapply, if returning an Option or Boolean can be used in match{} and pattern matching. Like apply it's just a def so can do whatever you dream up but the common usage is to extract value(s) from instances of the object's companion class.
From the libraries I've worked with serialization/deserialization defs tend to get named explicitly. E.g., write/read, show/read, toX/fromX, etc.
If you want to use apply/unapply for this purpose the only thing I'd suggest is changing to
def unapply(f: Foo): Option[JValue]
Then you could do something like:
val myFoo = Foo("""{name: "Whiskers", age: 7}""".asJson)
// use myFoo
val Foo(jval) = myFoo
// use jval