Return singleton/object from method - scala

How can I make this work?
def getSingleton[T <: scala.Singleton]: T = {
???
}
object X
val x = getSingleton[X.type]
Or similar, appreciate the signature may need to change slightly.

In Scala 2.13 there is built-in type class ValueOf 1 2 3
def getSingleton[T <: Singleton](implicit valueOf: ValueOf[T]): T = valueOf.value
In Scala 2.12 you can use type class Witness from Shapeless 1 2
// libraryDependencies += "com.chuusai" %% "shapeless" % "2.3.10"
import shapeless.Witness
def getSingleton[T <: Singleton](implicit witness: Witness.Aux[T]): T = witness.value
Or if you prefer not to depend on Shapeless you can write a macro
// libraryDependencies += scalaOrganization.value % "scala-reflect" % scalaVersion.value
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
def getSingleton[T <: Singleton]: T = macro getSingletonImpl[T]
def getSingletonImpl[T <: Singleton : c.WeakTypeTag](c: blackbox.Context): c.Tree = {
import c.universe._
// q"${weakTypeOf[T].typeSymbol.name.toTermName}"
// q"${weakTypeOf[T].dealias.typeSymbol.asClass.module}" // dealiased version
q"${symbolOf[T].asClass.module}" // not dealiased version
}
All the above works at compile time. If it's enough to get the value at runtime you can use Scala runtime reflection with TypeTag
import scala.reflect.runtime.{currentMirror => rm}
import scala.reflect.runtime.universe._
def getSingleton[T: TypeTag]: T =
rm.reflectModule(symbolOf[T].asClass.module.asModule).instance.asInstanceOf[T]
or with ClassTag
import scala.reflect.{ClassTag, classTag}
def getSingleton[T: ClassTag]: T =
rm.reflectModule(rm.moduleSymbol(classTag[T].runtimeClass)).instance.asInstanceOf[T]
or if you prefer not to depend on scala-reflect you can use Java reflection
def getSingleton[T: ClassTag]: T =
classTag[T].runtimeClass.getField("MODULE$").get(null).asInstanceOf[T]
In scala, is it possible to initialise a singleton object from a TypeTag?
Get the module symbol, given I have the module class, scala macro
Get instance of singleton type in scala
Scala object import in runtime

Related

Invoke constructor based on passed parameter

Constructing an object based on passed parameter. But the parameter is not String.
I found the solution how to do it with String
Scala instantiate objects from String classname
but I believe that it can be done nicer.
Let's say the following classes:
sealed trait Figure
object Figure {
final case class Circle(radius: Double) extends Figure
final case class Square(a: Double) extends Figure
}
And let's define a function (which doesn't make sense) which take a parameter based on I can invoke the proper constructor:
val construct123: Figure => Either[String, Figure] = (figure: Figure) => Right(figure.apply(1.23))
I want to invoke
construct123(Circle)
//or
construct123(Square)
Is it even possible?
The easiest would be to modify the signature of construct123 slightly
def construct123(figure: Double => Figure): Either[String, Figure] =
Right(figure(1.23))
construct123(Circle.apply) // Right(Circle(1.23))
construct123(Square.apply) // Right(Square(1.23))
construct123(Circle(_)) // Right(Circle(1.23))
construct123(Square(_)) // Right(Square(1.23))
construct123(Circle) // Right(Circle(1.23))
construct123(Square) // Right(Square(1.23))
Or construct123 can be written as a higher-order function
val construct123: (Double => Figure) => Either[String, Figure] =
figure => Right(figure(1.23))
Difference between method and function in Scala
Circle and Square in construct123(Circle) and construct123(Square) are not the case classes Circle and Square but their companion objects
Class companion object vs. case class itself
So actually you want to transform an object into an instance of its companion class. You can do this for example with a macro
// libraryDependencies += scalaOrganization.value % "scala-reflect" % scalaVersion.value
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
def construct123[A](figure: A): Either[String, Figure] = macro construct123Impl[A]
def construct123Impl[A: c.WeakTypeTag](c: blackbox.Context)(figure: c.Tree): c.Tree = {
import c.universe._
val companionClass = weakTypeOf[A].companion
q"_root_.scala.Right.apply(new $companionClass(1.23))" // using constructor of the case class
}
or
def construct123Impl[A: c.WeakTypeTag](c: blackbox.Context)(figure: c.Tree): c.Tree = {
import c.universe._
val A = symbolOf[A].asClass.module
q"_root_.scala.Right.apply($A.apply(1.23))" // using apply method of the companion object
}
Testing (in a different subproject):
construct123(Circle) // Right(Circle(1.23))
construct123(Square) // Right(Square(1.23))
// scalacOptions += "-Ymacro-debug-lite"
//scalac: scala.Right.apply(new Macros.Figure.Circle(1.23))
//scalac: scala.Right.apply(new Macros.Figure.Square(1.23))
//scalac: scala.Right.apply(Circle.apply(1.23))
//scalac: scala.Right.apply(Square.apply(1.23))
You can hide the work with macros in type classes (defined with whitebox implicit macros). The type class ToCompanion below is similar to HasCompanion in Get companion object of class by given generic type Scala (answer). The type class Generic from Shapeless (used below to define construct123) is also macro-generated. Some intros to type classes (ordinary, not macro-generated): 1 2 3 4 5 6 7 8 9
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
// type class
trait ToCompanion[A] {
type Out
}
object ToCompanion {
type Aux[A, Out0] = ToCompanion[A] {type Out = Out0}
// materializer
def apply[A](implicit tcc: ToCompanion[A]): ToCompanion.Aux[A, tcc.Out] = tcc
// def apply[A](implicit tcc: ToCompanion[A]): tcc.type = tcc
// instance of the type class
implicit def mkToCompanion[A, B]: ToCompanion.Aux[A, B] = macro mkToCompanionImpl[A]
// implicit def mkToCompanion[A]: ToCompanion[A] = macro mkToCompanionImpl[A] // then implicitly[ToCompanion.Aux[Circle, Circle.type]] doesn't compile in spite of white-boxity
def mkToCompanionImpl[A: c.WeakTypeTag](c: whitebox.Context): c.Tree = {
import c.universe._
val A = weakTypeOf[A]
val companion = A.companion
val ToCompanion = weakTypeOf[ToCompanion[A]]
q"new $ToCompanion { type Out = $companion }"
}
}
implicitly[ToCompanion.Aux[Circle, Circle.type]] // compiles
implicitly[ToCompanion.Aux[Circle.type, Circle]] // compiles
val tc = ToCompanion[Circle.type]
implicitly[tc.Out =:= Circle] // compiles
val tc1 = ToCompanion[Circle]
implicitly[tc1.Out =:= Circle.type] // compiles
// libraryDependencies += "com.chuusai" %% "shapeless" % "2.3.10"
import shapeless.{::, Generic, HNil}
def construct123[A, B <: Figure](figure: A)(implicit
toCompanion: ToCompanion.Aux[A, B],
generic: Generic.Aux[B, Double :: HNil]
): Either[String, Figure] = Right(generic.from(1.23 :: HNil))
construct123(Circle) // Right(Circle(1.23))
construct123(Square) // Right(Square(1.23))
Since all the classes are now known at compile time it's better to use compile-time reflection (the above macros). But in principle runtime reflection can be used too
import scala.reflect.runtime.{currentMirror => rm}
import scala.reflect.runtime.universe._
def construct123[A: TypeTag](figure: A): Either[String, Figure] = {
val classSymbol = symbolOf[A].companion.asClass
//val classSymbol = typeOf[A].companion.typeSymbol.asClass
val constructorSymbol = typeOf[A].companion.decl(termNames.CONSTRUCTOR).asMethod
val res = rm.reflectClass(classSymbol).reflectConstructor(constructorSymbol)(1.23).asInstanceOf[Figure]
Right(res)
}
or
import scala.reflect.ClassTag
import scala.reflect.runtime.{currentMirror => rm}
import scala.reflect.runtime.universe._
def construct123[A: TypeTag : ClassTag](figure: A): Either[String, Figure] = {
val methodSymbol = typeOf[A].decl(TermName("apply")).asMethod
val res = rm.reflect(figure).reflectMethod(methodSymbol).apply(1.23).asInstanceOf[Figure]
Right(res)
}
Or you can use structural types aka duck typing (i.e. also runtime reflection under the hood)
import scala.language.reflectiveCalls
def construct123(figure: { def apply(x: Double): Figure }): Either[String, Figure] =
Right(figure(1.23))

scala get generic type by class

Is it possible pass generic parameter using class:
def m(clazz: Class[_]): Unit = {
m2[] //here I want to exact type (that I should have because I have Class)
}
def m2[C: ClassTag]() : List[C] = {
println("hi")
List.empty
}
Any Ideas?
IIUC you want to call a method that requires a ClassTag while all you have is a Class. You can create a ClassTag from a Class like this:
def m(clazz: Class[_]): Unit = {
m2()(ClassTag(clazz))
}
ClassTags (as well as TypeTags and WeakTypeTags) are for persisting some compile-time information till runtime. You want to do something in reverse direction. You want, having runtime information (clazz: Class[_]), to do something at compile time (specify type parameter C of m2). So ClassTags are irrelevant.
You can call compiler at runtime
import scala.tools.reflect.ToolBox
import scala.reflect.runtime.currentMirror
object App {
val tb = currentMirror.mkToolBox()
def m(clazz: Class[_]): Unit = {
tb.eval(tb.parse(s"import App._; m2[${clazz.getName}]"))
}
def m2[C]() : List[C] = {
println("hi")
List.empty
}
def main(args: Array[String]): Unit = {
m(classOf[String]) //hi
}
}
libraryDependencies ++= Seq(
scalaOrganization.value % "scala-reflect" % scalaVersion.value,
scalaOrganization.value % "scala-compiler" % scalaVersion.value,
)

Printing MirroredElemTypes in Scala 3

I am trying to modify this standard example to print values with the types.
And I am stuck with p.MirroredElemTypes. I haven't found any API to traverse and stringify types.
To check MirroredElemTypes you can just summon
import scala.deriving.Mirror
case class A(i: Int, s: String, b: Boolean)
val m = summon[Mirror.Of[A]]
summon[m.MirroredElemTypes =:= (Int, String, Boolean)] // compiles
But if you want to print MirroredElemTypes you can do the following.
For some reason Typeable doesn't work now but in its error message it prints the type
// scalaVersion := "3.0.2"
// libraryDependencies += "org.typelevel" %% "shapeless3-typeable" % "3.0.3"
import shapeless3.typeable.Typeable
summon[Typeable[m.MirroredElemTypes]].describe
// Typeable for sum type scala.*:[scala.Int, scala.*:[scala.Predef.String, scala.*:[scala.Boolean, scala.Tuple$package.EmptyTuple]]] with no Mirror
Alternatively you can write a simple macro
import scala.quoted.*
inline def describe[A]: String = ${describeImpl[A]}
def describeImpl[T: Type](using Quotes): Expr[String] = {
import quotes.reflect.*
Literal(StringConstant(TypeRepr.of[T].dealias.show)).asExprOf[String]
}
// in a different file
describe[m.MirroredElemTypes]
// scala.*:[scala.Int, scala.*:[scala.Predef.String, scala.*:[scala.Boolean, scala.Tuple$package.EmptyTuple]]]
In Scala 3.2.0 + Shapeless 3.2.0 Typeable works properly
https://scastie.scala-lang.org/DmytroMitin/1R6N3ZOJS46DJJqtQDU0lw

Is there any trick to use macros in the same file they are defined?

I have the following code:
object Macros {
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
def hello(): Unit = macro hello_impl
def hello_impl(c: blackbox.Context)(): c.Expr[Unit] = {
import c.universe._
reify {
println("Hello World!")
}
}
}
object Main {
def main(args: Array[String]): Unit = {
Macros.hello()
}
}
It throws the following compilation error:
Error:(21, 17) macro implementation not found: hello
(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)
Macros.hello()
^
My question is: is there a way to "fool" the compiler in order to use macro expansions in the same file they are defined? My motivation is the following: I like to code in Scala, and lately I was submitting some problems in online judge Codeforces and some Scala constructions turned out to be very slow. So, I want to create some macro expansions in order to execute those constructions fast. But I cannot submit more than one file.
Thanks!
At the moment, this is not possible in production releases of Scala 2.10 and 2.11. We might be able to achieve this with scala.meta, but that's well in the future.
Depends on the meaning of "use". In principle you can use a macro (hello) in another method (foo) in the same file if you make the 2nd method a macro too (the 1st method call must be inside a quasiquote q"...", not reify{...})
import scala.language.experimental.macros
import scala.reflect.macros.blackbox // libraryDependencies += scalaOrganization.value % "scala-reflect" % scalaVersion.value
object Macros {
def hello(): Unit = macro hello_impl
def hello_impl(c: blackbox.Context)(): c.Expr[Unit] = {
import c.universe._
reify {
println("Hello World!")
}
}
}
object Main {
def foo(): Unit = macro fooImpl
def fooImpl(c: blackbox.Context)(): c.Tree = {
import c.universe._
q"Macros.hello()"
}
}
https://scastie.scala-lang.org/DmytroMitin/rom8yKvmSUGVk0GwtGzKqQ
The problem is that runnable def main(args: Array[String]): Unit can't be a macro.
Another option is reflective toolbox. A macro can't be defined with toolbox (actual compiler is needed for that)
import scala.reflect.runtime
import scala.reflect.runtime.universe.Quasiquote
import scala.tools.reflect.ToolBox // libraryDependencies += scalaOrganization.value % "scala-compiler" % scalaVersion.value
val rm = runtime.currentMirror
val tb = rm.mkToolBox()
tb.compile(q"""
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
def bar(): Unit = macro barImpl
def barImpl(c: Context)(): c.Tree = {
import c.universe._
EmptyTree
}
""")
//macro implementation reference has wrong shape. required:
//macro [<static object>].<method name>[[<type args>]] or
//macro [<macro bundle>].<method name>[[<type args>]]
But a macro can be run using toolbox
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
object Macros {
def hello(): Unit = macro hello_impl
def hello_impl(c: blackbox.Context)(): c.Expr[Unit] = {
import c.universe._
reify {
println("Hello World!")
}
}
}
import scala.reflect.runtime
import scala.reflect.runtime.universe.Quasiquote
import scala.tools.reflect.ToolBox
object Main {
def main(args: Array[String]): Unit = {
val rm = runtime.currentMirror
val tb = rm.mkToolBox()
tb.eval(q"Macros.hello()")
}
}
// Hello World!
https://scastie.scala-lang.org/DmytroMitin/rom8yKvmSUGVk0GwtGzKqQ/5
Regarding Codeforces the issue is that the compiler must be in classpath and calls via toolbox are comparatively slow.
Possible to identify/use Scala macros using reflection or similar? (Scala 3)
use a macro in the same file as it is defined? it is not possible, even not in Scala 3.
I refer to the description in Scala 3: Defining and Using Macros .
The macro implementation can be in the same project, but not in the same file as the macro usage.
See "Defining and Using Macros" chapter and "Suspended Files" info box.

Scodec - Coproducts could not find implicit value for parameter auto: scodec.codecs.CoproductBuilderAuto

On version:
"org.typelevel" %% "scodec-core" % "1.5.0"
I'm trying to use coproduct functionality, as shown in the test case demonstrate fixing the codec to a known subtype.
I keep getting the error: "could not find implicit value for parameter auto: scodec.codecs.CoproductBuilderAuto[my.class.here]"
I even copy pasted the example and could not get it to work:
import scalaz.\/
import shapeless._
import scodec.bits._
import scodec.codecs._
import scodec._
sealed trait Sprocket
object Sprocket {
implicit val discriminated: Discriminated[Sprocket, Int] = Discriminated(uint8)
}
def codec(d: Int): Codec[Sprocket] = Codec.coproduct[Sprocket].discriminatedBy(provide(d)).auto
I'll continue to look into this on my end, but was wondering if there was an issue fixed around this lately. I cloned the repo, and it worked from the clone - but not when I use the released version.
The error from the example code is caused by not having any subtypes of Sprocket defined. If there's at least 1 subtype of Sprocket, then Shapeless is able to generate a LabelledGeneric[Sprocket] instance where the representation is a discriminated union. The union is a coproduct of labelled subtypes.
Adding the following resolves the error:
case class Woozle(x: Int, y: Int) extends Sprocket
object Woozle {
implicit val discriminator: Discriminator[Sprocket, Woozle, Int] = Discriminator(1)
implicit val codec: Codec[Woozle] = (uint8 :: uint8).as[Woozle]
}
Note that you need both the discriminator and the codec implicits in the companion. If the discriminator isn't defined, you'll get the reported error. If the codec isn't defined, you'll get a diverging implicit error. Theoretically, the Woozle codec could be automatically derived if there's an implicit Codec[Int] in scope, but scalac isn't up to the task -- instead, it bails out with a diverging implicit expansion error. We hope to improve this with Shapeless 2.1.
For reference, full source:
import scalaz.\/
import shapeless._
import scodec.bits._
import scodec.codecs._
import scodec._
sealed trait Sprocket
object Sprocket {
implicit val discriminated: Discriminated[Sprocket, Int] = Discriminated(uint8)
}
case class Woozle(x: Int, y: Int) extends Sprocket
object Woozle {
implicit val discriminator: Discriminator[Sprocket, Woozle, Int] = Discriminator(1)
implicit val codec: Codec[Woozle] = (uint8 :: uint8).as[Woozle]
}
object Main extends App {
def codec(d: Int): Codec[Sprocket] = Codec.coproduct[Sprocket].discriminatedBy(provide(d)).auto
}
And build:
scalaVersion := "2.11.4"
libraryDependencies += "org.typelevel" %% "scodec-core" % "1.5.0"