scala,generics,scala-macros , How to substitute actual type arguments in a generic method to obtain final types of its value arguments?


How to substitute actual type arguments in a generic method to obtain final types of its value arguments?

Question:

Tag: scala,generics,scala-macros

I have a macro with a signature like

def generateSomething[A] = macro ...

That is, it accepts a type parameter. The type is expected to be a case class and so it always has corresponding apply method in its companion object.

This macro, among everything else, generates an invocation of this apply method, so, for example, for this class:

case class A(x: Int, y: String)

the following call will be generated:

A.apply(someFunction[Int], someFunction[String])

I extract parameter types for someFunction calls from apply signature.

Everything is fine unless A is parameterized:

case class A[T](x: Int, y: T)

With my current approach the following is generated for generateSomething[A[String]]:

A.apply[String](someFunction[Int], someFunction[T])

which is obviously not valid.

However, I don't know how to obtain apply's argument after all of its type parameters are known. That is, I don't know how to make sure that

generateSomething[A[String]]

generates

A.apply[String](someFunction[Int], someFunction[String])

and not the piece above. Is it possible?

Update

I think I should reformulate the question.

Suppose there is a class

case class A[T1, ..., Tn](x1: A1, ..., xm: Am)

where Ai can depend on arbitrary subset of Tk. Examples:

// T1 = T
// A1 = Int, A2 = T
case class B[T](x: Int, y: T)

// T1 = U, T2 = V
// A1 = Map[U, V], A2 = List[V]
case class C[U, V](m: Map[U, V], l: List[V])

// T1 = W
// A1 = W, A2 = W
case class D[W](t: W, u: W)

// No Ts
// A1 = String, A2 = Double
case class E(v: String, w: Double)  // no type parameters at all

I need to write a macro which accepts a type argument A and expands to A.apply method call with preprocessed arguments:

myMacro[A[U1, ..., Un]]

// expands to

A.apply[U1, ..., Un](preprocess[A1], ..., preprocess[An])

Uk here are actual type arguments which are substituted instead of Tk. For example (using classes above):

myMacro[B[String]] -> B.apply[String](preprocess[Int], preprocess[String])

myMacro[C[Int, Double]] -> C.apply[Int, Double](preprocess[Map[Int, Double]], preprocess[List[Double]])

myMacro[D[Long]] -> D.apply[Long](preprocess[Long], preprocess[Long])

myMacro[E] -> D.apply(preprocess[String], preprocess[Double])

You see, apply argument types can depend on type parameters. While these parameters are known to the macro (because it is always invoked with concrete types), I don't know how to "pass" these parameters "through" to apply function in order for preprocess type arguments to be correct.

Update 2

Here is loosely what I currently have.


Answer:

Something like:

case class X[A](a: A)

object TParamMacro {
  import scala.language.experimental.macros
  import scala.reflect.macros.whitebox.Context

  def m[A](): A = macro mImpl[A]

  def mImpl[A: c.WeakTypeTag](c: Context)(): c.Expr[A] = {
    import c.universe._
    val TypeRef(pre, sym, args) = weakTypeTag[A].tpe
    val t = args.head
    val expr = 
      if (t <:< typeOf[String]) q"""X.apply[$t]("hi")"""
      else if (t <:< typeOf[Int]) q"X.apply[$t](42)"
      else q"X.apply[$t](null)"
    c.Expr[A](expr)
  }
}

object Test extends App {
  Console println TParamMacro.m[X[String]]()
}

More example:

object TParamMacro {
  import scala.language.experimental.macros
  import scala.reflect.macros.whitebox.Context

  def m[A](): Any = macro mImpl[A]

  def mImpl[A: c.WeakTypeTag](c: Context)() = {
    import c.universe._
    val TypeRef(pre, sym, args) = weakTypeTag[A].tpe
    val t = args.head
    val expr = if (t <:< typeOf[String]) q"""X.apply[List[$t]](List.apply[$t]("hi"))"""
      else if (t <:< typeOf[Int]) q"X.apply[List[$t]](List.apply[$t](42))"
      else q"X.apply[List[$t]](Nil)"
    expr
  }
}

Where

Console println TParamMacro.m[X[String]]()

yields

X(List(hi))

Edit with the gist repaired:

package evaluator

import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context

object Evaluator {
  def preprocess[T]: T = ???

  def evaluate[A]: Any = macro evaluateImpl[A]

  def evaluateImpl[A: c.WeakTypeTag](c: Context): c.Expr[A] = {
    import c.universe._

    val tpe = weakTypeOf[A]
    val sym = tpe.typeSymbol.asClass

    require(sym.isCaseClass)

    val companionSym = sym.companion
    val companionTpe = companionSym.typeSignature
    val applyMethod = companionTpe.member(TermName("apply")).asMethod

    val paramTypes = applyMethod.paramLists.flatten.map(_.typeSignature)
    Console println s"apply($paramTypes)"

    val TypeRef(_, _, tpeTypeArgs) = tpe

    val from = applyMethod.typeParams
    val to   = tpeTypeArgs
    val arguments = paramTypes map { t =>
      val u = if (from.nonEmpty) t.substituteTypes(from, to) else t
      Console println s"param is $t, subst is $u"
      q"evaluator.Evaluator.preprocess[$u]"
    }

    c.Expr(q"$companionSym.apply[..$tpeTypeArgs](..$arguments)")
  }
}

So you're just substituting your "actual type args" for the method's type parameters. It's useful to use "parameter" for the formal parameter and "argument" for the actual arg in an application.

Sample:

package evaluator

case class A(x: Int, y: String)

case class B[T](x: Int, y: T)

case class C[U, T](x: Int, y: T, z: U)

object Test extends App {
  Evaluator.evaluate[A]
  Evaluator.evaluate[B[String]]
  Evaluator.evaluate[C[String, List[Int]]]
}

Using

-Xprint:typer

then

A.apply(evaluator.Evaluator.preprocess[Int], evaluator.Evaluator.preprocess[String]);
B.apply[String](evaluator.Evaluator.preprocess[Int], evaluator.Evaluator.preprocess[String]);
C.apply[String, List[Int]](evaluator.Evaluator.preprocess[Int], evaluator.Evaluator.preprocess[List[Int]], evaluator.Evaluator.preprocess[String])

Related:


Implicit Generic.Aux missing on conversion from Shapeless HList to case class


scala,shapeless,type-level-computation
I just recently started learning scala and today I decided I wanted to write a CSV parser that would load nicely into case classes but store the data in rows (lists) of Shapeless's HList object so that I could get some exposure to type-level programming. Here's what I have so...

Scala string replacement of entire words that comply with a pattern


string,scala,scala-collections,scala-string
In a string, how to replace words that start with a given pattern ? For instance replace each word that starts with "th", with "123", val in = "this is the example, that we think of" val out = "123 is 123 example, 123 we 123 of" Namely how to...

Generic method only compiles with one argument


java,generics
The below code will not compile, it says that the method is not applicable for the arguments. The interesting thing is that if I remove one of the arguments (doesn't matter which) then it compiles fine. public class Test1 { static Collection<? extends Shape> someColl = new ArrayList<Shape>(); public static...

Access key from mapValues or flatMapValues?


scala,apache-spark
In Spark 1.3, is there a way to access the key from mapValues? Specifically, if I have val y = x.groupBy(someKey) val z = y.mapValues(someFun) can someFun know which key of y it is currently operating on? Or do I have to do val y = x.map(r => (someKey(r), r)).groupBy(_._1)...

Difficulty with SBT


scala,sbt
I have started using scala sbt pretty recently. One thing which I find very difficult with SBT is to find the right dependency signature. for example, I am reading a blog which was written in 2014 and it says add the following libraryDependencies "net.liftweb" %% "lift-son" % "2.5+" "org.apache.httpcomponents" %%...

refer to scala function by name?


scala
Here is another stupid scala question regarding functions as first class objects in Scala. I'm very sorry if this is a repeat, as it probably is. In Python, Lisp, Perl, Scheme, etcetera I'm used to creating function values and assigning them names and passing them around to other functions, like...

How to effectively get indices of 1s for given binary string using Scala?


scala,functional-programming,higher-order-functions
Suppose we have a binary string such as 10010010. All I want is a function returning indices of 1s for that string: indicesOfOnes("10010010") -> List(0, 3, 6) indicesOfOnes("0") -> List() And what I implemented is: def indicesOfOnes(bs: String): List[Int] = { val lb = ListBuffer[Int]() bs.zipWithIndex.foreach { case (v, i)...

Passing a function foreach key of an Array


scala,apache-spark,scala-collections,spark-graphx
I have an array like that : val pairs: Array[(Int, ((VertexId, Seq[Int]), Int))] which generates this output : (11,((11,ArraySeq(2, 5, 4, 5)),1)) (11,((12,ArraySeq(7, 7, 8, 2)),1)) (11,((13,ArraySeq(5, 9, 8, 7)),1)) (1,((1,ArraySeq(1, 2, 3, 4)),1)) (1,((4,ArraySeq(1, 5, 1, 1)),1)) I want to build a Graph for each pairs._1. That means for...

Scala (Slick) HList splitting to case classes


scala,slick
currently I have a HList with more than 22 fields and now I want to split it to 2-3 case classes, is there an easy functional way to do it? Currently I use the following syntax: CaseClass1(c.head, c.tail.head, c.tail.tail.head, etc...) However that doesn't seem to be right since I have...

Scala first program issue


scala,recursion,case,frequency
I have just started to learn Scala after some experience with functional programming in other languages. def freq(c:Char, y:String, list:List[(Char,Int)]): List[(Char,Int)] = list match{ case _ => freq(c, y.filter(_ == c), list :: List((count(c,y),c))) case nil => list } In the above code I am getting an error when trying...

Retrieving TriangleCount


scala,apache-spark,spark-graphx
I'm trying to retrieve the amount of triangles from a graph using graphX. As I'm new to both Scala and graphX, I'm currently quite stuck. I'm creating a graph from an edgefile: 1 2 1 3 2 3 This should be 1 triangle. Next I'm using the build in function...

Scala running issue on eclipse


eclipse,scala
I configured everthing within eclipse for scala. I create a snippet to show you the issue, i can't see in run options run as scala application, i also tried to find my main class under build configuration option but i can't find it. How i can solve it?...

PlayFramework: value as is not a member of Array[Byte]


scala,playframework
I want to make file download from a database using Play framework. But when I use this code I get this message: value as is not a member of Array[Byte] And if I change Ok(bytOfImage.as("image/jpg")) to Ok(bytOfImage) it works good but I get a file with a name: secondindex without...

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


scala,scodec
I am trying to define an Scodec coproduct codec for communicating with an EELink GPS. Here is the code: import scodec.Codec import scodec.bits.ByteVector import scodec.codecs._ trait Message object Message { implicit val discriminated: Discriminated[ Message, Int ] = Discriminated(uint8) val codec: Codec[ Message ] = Codec.coproduct[ Message ].discriminatedByIndex(uint8) } case...

ZipList with Scalaz


list,scala,scalaz,applicative
Suppose I have a list of numbers and list of functions to apply to numbers: val xs: List[Int] = List(1, 2, 3) val fs: List[Int => Int] = List(f1, f2, f3) Now I would like to use an Applicative to apply f1 to 1, f2 to 2, etc. val ys:...

Scala rep separator for specific area of text


scala,parser-combinators
Imaging i've got following: --open Client: enter Nick Age 28 Rosewell, USA Client: enter Maria Age 19 Cleveland, USA --open-- I need a result close to the following: List(List(Nick, Age 28, Rosewell), List(Maria, Age19, Cleveland)) It can be as many clients inside open body as you can imagine, so the...

Scala unapplySeq extractor syntax


scala,pattern-matching,scala-2.11
I (inadvertently) came across a bit of pattern matching syntax I did not expect to compile and now cannot figure out. It appears related to unapplySeq. Note the case x List(_,_) part in this simple example: val xs = List(1, 2, 3) //> xs : List[Int] = List(1, 2, 3)...

Creating a generic / abstract “DBContext” Class for shared functionality among different DBs


c#,database,generics,inheritance,abstract-class
I am working on a C# project that is pulling data from SQL Server, ODBC data-sources and Oracle Databases at different times. At this point, I have created 3 different classes - Once for each type of DB access. However, I am seeing that 95% of the code is identical...

Register return Type


c#,generics,return-type
We have a C# class that holds session values for user in an MVC web application. Now I want to make the class more generic. Until now we have getters and setters for the session like public class WebAppLogin { public static WebAppLogin Current { get; //Gets the current Login...

My Scala program won't print anything


scala
Basically I'm trying to write a program that has a list of books and authors and then prints 2 things out, res1, which should print the book titles of the authors that have the name "Andrei" in it and res2 that should print the book titles that have the string...

implicit resolution for a function argument


scala,implicit,context-bound
I tried to implement mergesort in Scala. I got to the following: def mergeSort[A: Ordering](as: List[A]): List[A] = as match { case Nil => as case head :: Nil => as case _ => { val (l, r) = split(as) merge(mergeSort(l), mergeSort(r)) } } def split[A](as: List[A]): (List[A], List[A]) =...

Like clause not working with int column in slick


scala,slick,slick-2.0
Slick doesn't seem to support like clauses on int columns. The following code where Status.code is of int type doesn't seem to work. Would there be a workaround for this? val query = for { s <- Status if s.code like "1%" } yield (s) ...

Solving maze with Backtracking


scala,backtracking,maze
I am trying to solve a maze with scala using backtracking. My problem is that I keep on getting StackOverflow errors. I have tried qite alot of things but I always end up with a StackOverflow. findStart() and the getWay() show two approaches I have used. I know that it...

Type to impose required constrains on a double


scala,implicit-conversion
I would like to have a run time check on a Double, without having to scatter the check all over my code. I thought that defining an implicit class would do the job, something on the line: implicit class Probability(val x: Double) { require(x >= 0.0 && x <= 1.0,...

Zipping two arrays together with index in Scala?


arrays,scala,zip
I have two arrays populated with integers. They are the same size (val array1 and val array2). I want to fuse them together into tuples with their index as the third element. For example if we have val array1 = Array(5,2,6,2) and val array2 = Array(9,8,3,4) then I want to...

Preventing a class instantiation in Scala using Factory Pattern [duplicate]


scala,factory-pattern
This question already has an answer here: How to check constructor arguments and throw an exception or make an assertion in a default constructor in Scala? 2 answers Suppose that I have the following class defined in Scala: class ClassA(val n: Int) { ... } I want to limit...

Cannot invoke method with argument list of type KeyType in Swift


swift,generics
I am working on custom message dispatcher in Swift. I want to have dispatcher which can: dispatch enums as events or whatever what is Hashable. Every object which implements one protocol might be added as listeners Here is the code: import Foundation protocol EventDispatcherProtocol: class { typealias T: Hashable func...

Spray microservice assembly deduplicate


scala,sbt,akka,spray,microservices
I'm using this template to develop a microservice: http://www.typesafe.com/activator/template/activator-service-container-tutorial My sbt file is like this: import sbt._ import Keys._ name := "activator-service-container-tutorial" version := "1.0.1" scalaVersion := "2.11.6" crossScalaVersions := Seq("2.10.5", "2.11.6") resolvers += "Scalaz Bintray Repo" at "https://dl.bintray.com/scalaz/releases" libraryDependencies ++= { val containerVersion = "1.0.1" val configVersion = "1.2.1"...

Operand order in Scala List.prepend (::)


list,scala,operators
Odersky has brilliantly optimized Java syntax, enabling object calls without dots and parenthesis. I.e. instead of list.prepend(item), you now simply write list :: item, which also turns language operators into simple object methods. Here, List defines :: (prepend) operator. However, you normally write it vice-verse in Scala, using item ::...

Future yielding with flatMap


scala
Given Futures fa, fb, fc, I can use f: Function1[(A,B,C), Future[D]], to return a Future[D] either by: (for { a <- fa b <- fb c <- fc } yield (a,b,c)).flatMap(f) which has the unenviable property of declaring the variables a,b,c twice. or a.zip(b).zip(c).flatMap{ case (a, (b, c)) => f(a,...

How to code a generic Swift class which stores a Generator of the same type


swift,generics
I'm trying to write a class which handles objects of a homogenous type, and I'd like to feed in those objects using an (otherwise arbitrary) Generator of the same type. In essence this: class MyGenericClass<T> { var source : GeneratorType var itemsProcessed = [ T ]() init(source: GeneratorType) { self.source...

Scala slf4j dynamic file name


scala,logging,slf4j
I just successfully added Grizzled-SLF4J logger to my project using this link http://alvinalexander.com/scala/how-to-log-output-file-grizzled-slf4j-scala-simplelogger.properties But using this properties, there is no option to create dynamic file name: org.slf4j.simpleLogger.logFile = /tmp/myapp.log org.slf4j.simpleLogger.defaultLogLevel = info org.slf4j.simpleLogger.showDateTime = true org.slf4j.simpleLogger.dateTimeFormat = yyyy'/'MM'/'dd' 'HH':'mm':'ss'-'S org.slf4j.simpleLogger.showThreadName = true...

Play Framework Form Error Handling


scala,playframework,playframework-2.3,playframework-2.4
This is my view file containing the form that has to filled in by the user: @helper.form(call) { @helper.input(resumeForm("surname"), '_label -> "Surname") { (id, name, value, args) => <input name="@name" type="text" value="@value" placeholder="Enter your surname"> } } This is my custom field constructor: @(elements: helper.FieldElements) @if(!elements.args.isDefinedAt('showLabel) || elements.args('showLabel) == true)...

Collapse similar case statements in Scala


scala,functional-programming,pattern-matching
Is there an elegant way to do something like the following example using just one case statement? foobar match { case Node(Leaf(key, value), parent, qux) => { // Do something with parent & qux } case Node(parent, Leaf(key, value), qux) => { // Do something with parent & qux (code...

Ninject generic type xml binding


c#,xml,generics,ninject
I need to bind generic interface with generic implementation using Ninject.Extensions.Xml. The project is .net mvc project. Is there any way to accomplish this ? The class: public class JsonProvider<T> : IJsonProvider<T> where T: new() { ... } Xml configuration (Not working): <bind service="Base.IJsonProvider, Base" to="Base.JsonProvider, Base" name ="Config"/> ...

How to unmarshall akka http request entity as string?


json,scala,akka-http
I'm trying to unmarshall request payload as string, but for some reason it's failing. My code: path("mypath") { post { decodeRequest { entity(as[String]) {jsonStr => //could not find implicit value for...FromRequestUnmarshaller[String] complete { val json: JsObject = Json.parse(jsonStr).as[JsObject] val jsObjectFuture: Future[JsObject] = MyDatabase.addListItem(json) jsObjectFuture.map(_.as[String]) } } } } } In...

Generic TypeCode Type Checking?


c#,generics
Should I avoid type checking with generics? Not using traditional type checking comparisons(myvar is int), but rather using the type's typecode. Using generics, with type checking allows you to create a single method without parameters that supports the tasks of regular overloaded methods. This is a problem with parameter-less methods,...

Implementing map on a tree using fold


scala,haskell
I am trying to implement a map using fold. I could do so in Haskell data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show) foldTree :: Tree a -> b -> (b -> a -> b -> b) -> b foldTree EmptyTree d _ =...

SCALA: change the separator in Array


arrays,string,scala,delimiter
I have an Array like this. scala> var x=Array("a","x,y","b") x: Array[String] = Array(a, x,y, b) How do I change the separator comma in array to a :. And finally convert it to string like this. String = "a:x,y:b" My aim is to change the comma(separators only) to other separator(say,:), so...

Spray route get response from child actor


scala,akka,spray
I am trying to figure out how I can setup a Master Actor that calls the appropriate children, in support of some spray routes where I am trying to emulate db calls. I am new to akka / spray, so just trying to gain a better understanding of how you...

How to instantiate lexical.Scanner in a JavaTokenParsers class?


scala,parsing,lexical-scanner
I am writing a parser which inherits from JavaTokenParsers in that I have a function as follow: import scala.util.parsing.combinator.lexical._ import scala.util.parsing._ import scala.util.parsing.combinator.RegexParsers; import scala.util.parsing.combinator.syntactical.StdTokenParsers import scala.util.parsing.combinator.token.StdTokens import scala.util.parsing.combinator.lexical.StdLexical import scala.util.parsing.combinator.lexical.Scanners import scala.util.parsing.combinator.lexical.Lexical import...

Is this definition of a tail recursive fibonacci function tail-recursive?


scala,f#,functional-programming,tail-recursion,continuation-passing
I've seen around the following F# definition of a continuation-passing-style fibonacci function, that I always assumed to be tail recursive: let fib k = let rec fib' k cont = match k with | 0 | 1 -> cont 1 | k -> fib' (k-1) (fun a -> fib' (k-2)...

How to use the Akka ask pattern without blocking


scala,asynchronous,akka,future
Hi I have a actor which is responsible for fetching data from a database, turning it into a list and sending it back to the sender. I am using the ask pattern to receive response from my actor, because I don't want to use await.result because this approach will block...

How to generalize the round methods


scala
I have the following four methods, using BigDecimal to round a number: private def round(input: Byte, scale: Int): Byte = { BigDecimal(input).setScale(scale, RoundingMode.HALF_UP).byteValue() } private def round(input: Short, scale: Int): Short = { BigDecimal(input).setScale(scale, RoundingMode.HALF_UP).shortValue() } private def round(input: Int, scale: Int): Int = { BigDecimal(input).setScale(scale, RoundingMode.HALF_UP).intValue() } private def...

How to define a Regex in StandardTokenParsers to identify path?


regex,scala,parsing,lexical-analysis
I am writing a parser in which I want to parse arithmetic expressions like: /hdfs://xxx.xx.xx.x:xxxx/path1/file1.jpg+1 I want to parse it change the infix to postfix and do the calculation. I used helps from a part of code in another discussion as well. class InfixToPostfix extends StandardTokenParsers { import lexical._ def...

Is there any scala library that treat tuples as monads


scala,tuples,monads
Is there any scala library that enriches basic scala tuples with monad syntax. Something similar to the Writer monad but adjusted for usage with tuples. What I look for: val pair = (2, "as") pair >>= (a => point(a+1)) should equal to (3, "as"). As well as for (p <-...

Scala - Option Type Var Manipulation


scala,scala-option
I am working on an online exercise practicing Options and threads, both of which I have very little experience. The online exercise comes with a test suite, so right now I am trying to get my Option test cases to pass before I move on to the thread test cases....

How can I pass N number of generic arguments to a typedef function pointer?


c++,generics,typedef
I have this typedef function pointer plot: typedef void(*plot)(); How can I pass a generic argument to it (Something like this): template<typename T> typedef void(*plot)(T); And then, how can I pass N number of generic arguments to it? template<typename T> typedef void(*plot)(T ...); ...

Convert RDD[Map[String,Double]] to RDD[(String,Double)]


scala,apache-spark,rdd
I did some calculation and returned my values in a RDD containing scala map and now I want to remove this map and want to collect all keys values in a RDD. Any help will be appreciated....

How to reuse MappedColumnType in Table classes?


scala,playframework,slick
The use of MappedColumnType is demonstrated in this example: https://github.com/playframework/play-slick/blob/master/samples/computer-database/app/dao/ComputersDAO.scala#L21 How can I reuse dateColumnType in another table class?...