I am new to Scala and now I went through a construct like the following:
scala> var a = List(('a',1),('b',2))
I googled this one and it turned out to be a Scala tuple2. My question is:
Is this a special Scala constructs i.e whenever I use ('a',3), scala creates a Tuple2 or there is something configured that I can change to make scala create MyTuple2 instead of Tuple2?
Can I create my own class that makes scala use it whenever I use its constructor?
As pointed out in the comments, Tuple2 is just a class like any other. You can create your own like this:
case class MyTuple2[A, B](a: A, b: B)
val myTuples: List[MyTuple2[String, Int]] = List(MyTuple2("a", 1), MyTuple2("b", 2))
As for the syntax, you cannot override the syntax-sugar of normal tuples (afaik). There are certainly things you could do with implicits or macros to fake it, but I'd strongly encourage you not to do that as it's highly surprising to anyone else if something looks like a standard Tuple2, but doesn't behave like one.
Related
Does Scala have a way to get the contained class(es) of a collection? i.e. if I have:
val foo = Vector[Int]()
Is there a way to get back classOf[Int] from it?
(Just checking the first element doesn't work since it might be empty.)
You can use TypeTag:
import scala.reflect.runtime.universe._
def getType[F[_], A: TypeTag](as: F[A]) = typeOf[A]
val foo = Vector[Int]()
getType(foo)
Not from the collection itself, but if you get it a parameter from a method, you could add an implicit TypeTag to that method to obtain the type at runtime. E.g.
def mymethod[T](x: Vector[T])(implicit tag: TypeTag[T]) = ...
See https://docs.scala-lang.org/.../typetags-manifests.html for details.
Technically you can do it by using TypeTag or Typeable/TypeCase from Shapless library (see link). But I just want to note that all these tricks are really very advanced solutions when there is no any better way get the task done without digging inside type parameters.
All type parameters in scala and java are affected by type erasure on runtime, and if you сatch yourself thinking about extracting these information from the class it might be a good sign to redesign the solution that you are trying to implement.
I am new to scala. Currently I am trying to develop a calculator as scala project.
But while trying to find the sum I am getting problem. The following code doesn't compile.
def add [T](values :List[T]) : Option[T]={
if (values.isInstanceOf[String]) {
None
}
else if(values.isInstanceOf[Int] || values.isInstanceOf[Long] || values.isInstanceOf[Double]) {
Some(values.sum)
}
}
When you're new to a language, it is important to start slow and discover the abstractions rather than impose them right away without the experience to make it work. I also think it is a bad idea to just rely on standard library functions (unless you are in a hurry) like sum or to look at third-party libraries until you fully understand what the standard library offers.
So in other words, first let's look at ways to solve the problem just for Int:
def add(values: List[Int]) = values.reduce((a, b) => a + b)
The reduce function works because the type of the result matches the type of what is in the list. The contents are Ints, and the sum is an Int. You will also find this can be simplified with some syntactic sugar:
def add(values: List[Int]) = values.reduce(_ + _)
Wait until you see all the ways underscores get used in Scala.
As you keep studying, you will find that in order to accumulate a value that is a different type than what's in the list, you can use one of the fold* methods. But they can work here too, so for example you could also do this:
def add(values: List[Int]) = values.foldLeft(0)(_ + _)
Now try to define the same function for Long, Double, or even String. You will find the implementations will be almost identical.
It's only when you see implementations that look really similar if not identical that you should even think about abstractions. One option to solve this problem is with type classes. They aren't easy for beginners though. Daniel Westheide wrote a great post on the topic, and frankly you would do well to read the whole series as you learn Scala.
I've really simplified things and glossed over a lot of topics (like why foldLeft has two parameter lists with the first one being 0 or what those crazy implicit things are in Daniel's type classes post), but my advice is to be patient and move slowly. Scala isn't easy, but you'll get it.
(But if you are in a hurry and you are a beginner, I think you are better off just using sum and then writing separate functions for each type. This would be an example of what agile author Kenny Rubin would call "necessary" or "unavoidable" technical debt, and that's to be expected from beginners. Just refactor later.)
Or more generic (example with amm):
# import $ivy.`org.typelevel:cats_2.12:0.8.1`
import $ivy.$
# import cats._, cats.implicits._
import cats._, cats.implicits._
# List(1, 2, 3).combineAll
res2: Int = 6
# List("1", "2", "3").combineAll
res3: String = "123"
# List(List(1, 2), List(), List(3)).combineAll
res5: List[Int] = List(1, 2, 3)
Or via fiddle. It works by using the Monoid and Traversable typeclass.
I'm using the Reader monad in Scala as provided by the scalaz library. I'm familiar with this monad as defined in Haskell. The problem is that I cannot find the functions equivalent to return, local, and sequence (among others).
Currently I use constructs that I do not like since I'm repeating myself or making my code a bit obscure.
Regarding return, I'm currently using:
Reader{_ => someValue}
I'd rather just use a construct like unit(someValue), but I could not find anything on the internet. There are tutorials like this one that use the approach above, and which I consider not optimal.
Regarding local I also have to do something similar: instead of typing something like: local f myReader I have to unfold its definition:
Reader{env => myReader.run(f(env))
Finally, sequence is a bit closer to what I would expect (being a Haskell refugee doing Scala):
readers: List[Reader[Env, T]]
readerTs: Reader[Env, List[T]] = readers.sequenceU
My problem with this implementation is that, being relatively new to Scala, the type of sequenceU
final class TraverseOps[F[_],A] private[syntax](val self: F[A])(implicit val F: Traverse[F]) extends Ops[F[A]] {
//...
def sequenceU(implicit G: Unapply[Applicative, A]): G.M[F[G.A]]
appears like rather obscure, and seems like black magic. Ideally I would like to use a sequence operations on Monads.
Is there a better translation of these constructs to Scala available on scalaz or similar library? I'm not married to any Functional library for Scala, so any solution using other libraries will do, although I'd rather have an answer using scalaz, since I already implemented my code using it.
To make the things simpler, I fill in some types. Changing them to defs with generic types should still work.
Also I extracted the ReaderInt type, to avoid confusion with type lambdas.
return / pure / point
Scala does not have automatic typeclass resolution, so you need to provide them implicitly. For Kleisli (being a monad transformer for reader),
Kleisli[Id, ?, ?] is enough
implicit val KA = scalaz.Kleisli.kleisliIdApplicative[Int]
type ReaderInt[A] = Kleisli[Id.Id, Int, A]
val alwaysHello = KA.point("hello")
or with imported syntax:
import scalaz.syntax.applicative._
val alwaysHello = "hello".point[ReaderInt]
So as a general rule, you
1) import the applicative intance, which usually located in scalaz.std.something.somethingInstance
2) import scalaz.syntax.something._
3) then you can write x.point[F], where F is your applicative.
local
Not sure, that it answers your question, but Kleisli has a local method.
val f: String ⇒ Int = _.length
val alwaysEleven = alwaysHello local f
sequencing
The same way, you are free to choose to use syntax for or to specify type classes explicitly.
import scalaz.std.list.listInstance
val initial: List[ReaderInt[String]] = ???
val sequenced: ReaderInt[List[String]] = Traverse[List].sequence[ReaderInt, String](initial)
import scalaz.syntax.traverse._
val z = x.sequence[ReaderInt, String]
I prefer not to use sequenceU, which uses Unapply typelcass to infer the G type, because sometimes scala has troubles of figuring out the right one.
And I personally do not find it messy to put in some types myself.
It may worth to look into cats, though it does not have much yet.
is there a way to create an alias for a scala keyword? in particular i have some boilerplate syntax that involves "val" and in order to make it easier to read i'd like to be able to type something "##" instead and have that translated to val.
Edit:
In some cases, it might be very convenient to be able to replace "lazy val", not just "val". The use case has to do with a function that acts as a python decorator. It looks like this:
lazy val function = Decorate(function_ _)
def function_(x: Int, ...) = { ... }
it would be a lot nicer if it looked like this:
# function = Decorate(function_ _)
def function_(x: Int, ...) = { ... }
just so that there's not a val stacked on top of a def, where both names are extremely similar. (the function_ name is not meant to be called, so it's the cleanest to make the names similar.)
No, there isn't.
(filler so SO will let me post)
Ouch! This isn't particularly idiomatic Scala.
To start with, you're naming a method "function_", they're not the same thing, a method is simply a member of some class, a Function is an object in its own right (although a method can be "lifted" to a function by the compiler, in a similar fashion to the autoboxing of primitives).
Second, what is Decorate? The initial uppercase letter suggests that it's a singleton, therefore an object and the only actual "Function" in that expression!
Could you post a bit more info as to what the method and decorator actually do, so that I can give you a better example as to how you might achieve the same in Scala?
I guess one could write a Scala Compiler Plugin to achieve this. At least the Eclipse Plugin actually uses the original Scala Compiler, so it might actually work nicely with the IDE.
Other then that: Daniel C. Sobral is correct: No, there isn't.
Still it sounds like a lot of trouble for a little gain.
If function_ is never meant to be called directly, why not write
lazy val function = Decorate { (x: Int, ...) => ... }
or even
/**
* This version makes it more explicit that it's a function value.
*/
lazy val function: (Int, ...) => ReturnType =
Decorate { (x, ...) => ... }
Some caution is advised: conciseness and terseness are two different things. Here, it looks like you're trying to buy a few keystrokes at a very high price in terms of readability.
Update:
If you really want to achieve a simpler syntax for this sort of thing, you will need a compiler plugin. If you're going to go that far, I'd suggest using an annotations-based syntax that's likely to be pretty intuitive for Java/Scala developers:
#decorate(Memoize)
def slowFn(i: Int) = { ... }
I want to come out a way to define a new method in some existing class in scala.
For example, I think the asInstanceOf[T] method has too long a name, I want to replace it with as[T].
A straight forward approach can be:
class WrappedAny(val a: Any) {
def as[T] = a.asInstanceOf[T]
}
implicit def wrappingAny(a: Any): WrappedAny = new WrappedAny(a)
Is there a more natural way with less code?
Also, a strange thing happens when I try this:
scala> class A
defined class A
scala> implicit def toA(x: Any): A = x
toA: (x: Any)A
scala> toA(1)
And the console hang. It seems that toA(Any) should not pass the type checking phase, and it can't when it's not implicit. And putting all the code into a external source code can produce the same problem. How did this happen? Is it a bug of the compiler(version 2.8.0)?
There's nothing technically wrong with your approach to pimping Any, although I think it's generally ill-advised. Likewise, there's a reason asInstanceOf and isInstanceOf are so verbosely named; it's to discourage you from using them! There's almost certainly a better, statically type-safe way to do whatever you're trying to do.
Regarding the example which causes your console to hang: the declared type of toA is Any => A, yet you've defined its result as x, which has type Any, not A. How can this possibly compile? Well, remember that when an apparent type error occurs, the compiler looks around for any available implicit conversions to resolve the problem. In this case, it needs an implicit conversion Any => A... and finds one: toA! So the reason toA type checks is because the compiler is implicitly redefining it as:
implicit def toA(x: Any): A = toA(x)
... which of course results in infinite recursion when you try to use it.
In your second example you are passing Any to a function that must return A. However it never returns A but the same Any you passed in. The compiler then tries to apply the implicit conversion which in turn does not return an A but Any, and so on.
If you define toA as not being implicit you get:
scala> def toA(x: Any): A = x
<console>:6: error: type mismatch;
found : Any
required: A
def toA(x: Any): A = x
^
As it happens, this has been discussed on Scala lists before. The pimp my class pattern is indeed a bit verbose for what it does, and, perhaps, there might be a way to clean the syntax without introducing new keywords.
The bit about new keywords is that one of Scala goals is to make the language scalable through libraries, instead of turning the language into a giant quilt of ideas that passed someone's criteria for "useful enough to add to the language" and, at the same time, making other ideas impossible because they weren't deemed useful and/or common enough.
Anyway, nothing so far has come up, and I haven't heard that there is any work in progress towards that goal. You are welcome to join the community through its mailing lists and contribute to its development.