This question already has answers here:
Understanding implicit in Scala
(7 answers)
Closed 2 years ago.
I have to solve this quinz but i can't find the correct answer.
trait Physics {
implicit def air: Gaz,
implicit def condense(implicit gaz: Gaz): Liquid,
implicit def freeze(implicit liquid: Liquid): Solid
implicitly[Solid]
}
Can you rewrite the last line with the inferred parameter explicitly written?
Hint: It should look like
implicitly[Solid](...
Thank you so much!
Here is a hint: first consider implicitly is just a method like any other
def implicitly[T](implicit e: T): T = e
Lets remove the keyword implicit such that
def implicitly[T](e: T): T = e
Given implicitly is just a method taking arguments, think about what would you have to do to make compiler happy and have method implicitly return a Solid?
Related
This question already has an answer here:
What does ?=> mean in Scala?
(1 answer)
Closed 1 year ago.
I cannot find explanation of the following syntax rule:
FunType ::= FunTypeArgs (‘=>’ | ‘?=>’) Type
?=> denotes a context function type.
Context functions are written using ?=> as the “arrow” sign. They are applied to synthesized arguments, in the same way methods with context parameters are applied. For instance:
given ec: ExecutionContext = ...
def f(x: Int): ExecutionContext ?=> Int = ...
...
f(2)(using ec) // explicit argument
f(2) // argument is inferred
So, if you think of A => B as being analogous to
def foo(a: A): B
Then you should think of A ?=> B as being analogous to
def foo(using a: A): B
It's just like a regular function except that the argument is taken as a context parameter. You can refuse to supply it (and it will be inferred from all of the givens in-scope, similar to implicit in Scala 2), or you can explicitly supply it using the using keyword.
This question already has answers here:
Result type of an implicit conversion must be more specific than AnyRef
(4 answers)
Closed 4 years ago.
def testLong(v: Any): Unit = {
println(v.getClass) // print: class java.lang.Long
}
testLong(103L) // compile passed
from last snippet, it shows that the variable v is class java.lang.Long.And it's a subclass of java.lang.Object.
We also know from the scala Unified types system the AnyRef is equals to java.lang.Object type. But why it compile failed as follows:
def testLong(v: AnyRef): Unit = {
println(v.getClass)
}
testLong(103L) // compile failed
Probably the reason why the implicit conversion was not used in the second example is because this:
// val l: AnyRef = 10L
// error: the result type of an implicit conversion must be more specific than AnyRef.
This answer may explain welll why this happens.
However, you can re-write your method for make it work using an implicit evidence.
def testLong[T](v: T)(implicit ev: T => AnyRef): Unit = {
println(v.getClass)
}
testLong(10L)
// class java.lang.Long
Curious enough, if you make the method specific to Long only, the printed class changes.
def testLong(v: Long)(implicit ev: Long => AnyRef): Unit = {
println(v.getClass)
}
testLong(10L)
// long
This question already has answers here:
What is a "context bound" in Scala?
(4 answers)
Closed 4 years ago.
I'm learning to use Scala cats library. Quite often I see this type of definition like
implicit def validatedApplicative[E : Semigroup]: Applicative[Validated[E, ?]] = ???
def parallelValidate[E : Semigroup, A, B, C](v1: Validated[E, A], v2: Validated[E, B])(f: (A, B) => C): Validated[E, C] = ???
def parse[A : Read](key: String): Validated[ConfigError, A] = ???
Can someone tell me why we are defining the A is of type ClassName in generics for [A : ClassName]?
What additional benefit we get when we write a method definition as
def parse[A : Read](key: String): Validated[ConfigError, A]
instead of
def parse(key: String): Validated[ConfigError, Read]
for a method declaration?
Cats uses type classes everywhere, that's something you should look into it when you want to learn more of the functional approach.
Type classes can be defined like:
trait Read[A] {
def read(in: A): String
}
when specifying a type like this: [A : Read]
you are requesting that the type used A must have in scope an implementation of the typeClass Read.
This makes writing generic code quite simple compare of requiring your type to extend many different interfaces...
I believe in cats website there are some blogs introducing to type classes
This question already has answers here:
Why doesn't the example compile, aka how does (co-, contra-, and in-) variance work?
(4 answers)
Closed 7 years ago.
In scala Option class is declared like
sealed abstract class _Option[+A]
case object _None extends _Option[Nothing] {}
final case class _Some[+A](x: A) extends _Option[A] {}
What is [+A]? Why not just [A]? Could it be [-A] and what it would mean?
Sorry if it is a duplicate but I couldn't find the answer on SO.
It declares the class to be covariant in its generic parameter. For your example, it means that Option[T] is a subtype of Option[S] if T is a subtype of S. So, for example, Option[String] is a subtype of Option[Object], allowing you to do:
val x: Option[String] = Some("a")
val y: Option[Object] = x
Conversely, a class can be contravariant in its generic parameter if it is declared as -A.
Read above variances in Scala in the docs here.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What do <:<, <%<, and =:= mean in Scala 2.8, and where are they documented?
e.g. in this example, from scala-arm 1.0:
def toTraversable[B](implicit ev: R <:< TraversableOnce[B]): Traversable[B] =
new ManagedTraversable[B,R] {
val resource = self
override protected def internalForeach[U](resource: R, g : B => U) : Unit =
ev(resource).foreach(g)
}
<:< (and similar strange looking constructs) are defined in Predef.scala (source at scala-lang.org), which is probably the best resource for working out what they are.
In general, classes like that can be used to provide further bounds on the type parameters within the scope of a particular method. <:< in particular is used to require that R is a subtype of TraversableOnce[B].
The description from Predef is:
To constrain any abstract type T that's in scope in a method's
argument list (not just the method's own type parameters) simply
add an implicit argument of type T <:< U, where U is the required
upper bound; or for lower-bounds, use: L <:< T, where L is the
required lower bound.