Given a Tuple type
type T = (String, Int, String)
Is there any way I can get a type T1, where T1 would be
type T1 = (MyClass, String, Int, String)
I would love to be able to declare a class like
class TupleTypes[T] extends AnotherClass[T1]
Note: The tuple size is not known and
type T1 = (MyClass, T)
will not return what I want, it will return (MyClass, (String, Int, String)) which is different.
Thanks
You can do this using the HList to tuple conversions from shapeless.
scala> import shapeless._ ; import Tuples._
import shapeless._
import Tuples._
scala> class MyClass ; val m = new MyClass
defined class MyClass
m: MyClass = MyClass#3859023a
scala> val t1 = ("foo", 23, "bar")
t1: (String, Int, String) = (foo,23,bar)
scala> val t2 = (m :: t1.hlisted) tupled
t2: (MyClass, String, Int, String) = (MyClass#3859023a,foo,23,bar)
In my opinion there are no such constructs for tuples, but HList have a behavior very similar to the one you showed. They are considered has advanced type programming structure, and usage can be difficult depending on what you want to achieve. Here are an excellent starter and a nice implementation.
late to the party, but in the event that you are seeking a "better" solution in regard to the ScalaQuery problem, try this:
1) create mapper base class with ID
import org.scalaquery.ql.extended.{ExtendedTable => Table}
abstract class Mapper[T](table: String) extends Table[T](None, table) {
def id = column[Int]("id", O PrimaryKey)
}
2) extend mapper base using case class/companion object (i.e. not tuple based)
case class Foo (bar: String)
object Foos extends _Mapper[Foo]("foo") {
def foo = column[String]("foo")
}
then you can do something like:
def show: List[Foo] = {
val q = (for { f <- Foos } yield f)
val foos = db withSession {
foos.list map { case t:T => t }
}
render(foos)
}
and have a navigable object to work with (vs. index-based tuple).
Now, sometimes you don't want an enormous object graph when you only need a subset of fields from a group of entities.
That's where projections come in, just create a case class that represents the set of fields that you want and, voila, a navigable projection object to work with:
case class Yum (foo: String, baz: String)
def show: List[Yum] = {
val q = (for { f <- Foos; b <- Bars; if f.id is b.fooID } yield (f.foo, b.baz))
val yums = db withSession {
yums.list map { case t:T => t }
}
render(yums)
}
Fairly simple, should be encapsulated in a cake driven DAO, but the general principle is: take the case class/object route.
Should note that ScalaQuery kicks unbelievable azz, Zeiger is brilliant! (as are many in the Scala community, future is looking bright on Scala way ;-))
Related
Assuming that I have a Generic superclass:
class GenericExample[T](
a: String,
b: T
) {
def fn(i: T): T = b
}
and a concrete subclass:
case class Example(
a: String,
b: Int
) extends GenericExample[Int](a, b)
I want to get the type parameter of function "fn" by scala reflection, so I select and filter through its members:
import ScalaReflection.universe._
val baseType = typeTag[Example]
val member = baseType
.tpe
.member(methodName: TermName)
.asTerm
.alternatives
.map(_.asMethod)
.head
val paramss = member.paramss
val actualTypess: List[List[Type]] = paramss.map {
params =>
params.map {
param =>
param.typeSignature
}
}
I was expecting scala to give me the correct result, which is List(List(Int)), instead I only got the generic List(List(T))
Crunching through the document I found that typeSignature is the culprit:
* This method always returns signatures in the most generic way possible, even if the underlying symbol is obtained from an
* instantiation of a generic type.
And it suggests me to use the alternative:
def typeSignatureIn(site: Type): Type
However, since class Example is no longer generic, there is no way I can get site from typeTag[Example], can anyone suggest me how to get typeOf[Int] given only typeTag[Example]? Or there is no way to do it and I have to revert to Java reflection?
Thanks a lot for your help.
UPDATE: After some quick test I found that even MethodSymbol.returnType doesn't work as intended, the following code:
member.returnType
also yield T, annd it can't be corrected by asSeenFrom, as the following code doesn't change the result:
member.returnType.asSeenFrom(baseType.tpe, baseType.tpe.typeSymbol.asClass)
There are two approaches which I can suggest:
1) Reveal generic type from base class:
import scala.reflect.runtime.universe._
class GenericExample[T: TypeTag](a: String, b: T) {
def fn(i: T) = "" + b + i
}
case class Example(a: String, b: Int) extends GenericExample[Int](a, b) {}
val classType = typeOf[Example].typeSymbol.asClass
val baseClassType = typeOf[GenericExample[_]].typeSymbol.asClass
val baseType = internal.thisType(classType).baseType(baseClassType)
baseType.typeArgs.head // returns reflect.runtime.universe.Type = scala.Int
2) Add implicit method which returns type:
import scala.reflect.runtime.universe._
class GenericExample[T](a: String, b: T) {
def fn(i: T) = "" + b + i
}
case class Example(a: String, b: Int) extends GenericExample[Int](a, b)
implicit class TypeDetector[T: TypeTag](related: GenericExample[T]) {
def getType(): Type = {
typeOf[T]
}
}
new Example("", 1).getType() // returns reflect.runtime.universe.Type = Int
I'm posting my solution: I think there is no alternative due to Scala's design:
The core difference between methods in Scala reflection & Java reflection is currying: Scala method comprises of many pairs of brackets, calling a method with arguments first merely constructs an anonymous class that can take more pairs of brackets, or if there is no more bracket left, constructs a NullaryMethod class (a.k.a. call-by-name) that can be resolved to yield the result of the method. So types of scala method is only resolved at this level, when method is already broken into Method & NullaryMethod Signatures.
As a result it becomes clear that the result type can only be get using recursion:
private def methodSignatureToParameter_ReturnTypes(tpe: Type): (List[List[Type]], Type) = {
tpe match {
case n: NullaryMethodType =>
Nil -> n.resultType
case m: MethodType =>
val paramTypes: List[Type] = m.params.map(_.typeSignatureIn(tpe))
val downstream = methodSignatureToParameter_ReturnTypes(m.resultType)
downstream.copy(_1 = List(paramTypes) ++ methodSignatureToParameter_ReturnTypes(m.resultType)._1)
case _ =>
Nil -> tpe
}
}
def getParameter_ReturnTypes(symbol: MethodSymbol, impl: Type) = {
val signature = symbol.typeSignatureIn(impl)
val result = methodSignatureToParameter_ReturnTypes(signature)
result
}
Where impl is the class that owns the method, and symbol is what you obtained from Type.member(s) by scala reflection
Given the following classes:
case class AddRequest(x: Int, y: Int)
case class AddResponse(sum: Int)
case class ToUppercaseRequest(str: String)
case class ToUppercaseResponse(upper: String)
How do I define in a typesafe manner some function:
def process(req: ???): ???
Such that the following should hold true:
val r1: AddResponse = process(AddRequest(2, 3))
val r2: ToUppercaseResponse = process(ToUppercaseRequest("aaa"))
Also, the following should not compile:
val r3 = process("somestring")
This is both entirely possible and a totally reasonable thing to do in Scala. This kind of thing is all over Shapeless, for example, and something similar (but less principled) is the basis of the magnet pattern that shows up in Spray, etc.
Update: note that the following solution assumes that "given the following classes" means you don't want to touch the case classes themselves. If you don't care, see the second part of the answer below.
You'd want a type class that maps input types to output types:
case class AddRequest(x: Int, y: Int)
case class AddResponse(sum: Int)
case class ToUppercaseRequest(str: String)
case class ToUppercaseResponse(upper: String)
trait Processable[In] {
type Out
def apply(in: In): Out
}
And then some type class instances:
object Processable {
type Aux[I, O] = Processable[I] { type Out = O }
implicit val toUppercase: Aux[ToUppercaseRequest, ToUppercaseResponse] =
new Processable[ToUppercaseRequest] {
type Out = ToUppercaseResponse
def apply(in: ToUppercaseRequest): ToUppercaseResponse =
ToUppercaseResponse(in.str.toUpperCase)
}
implicit val add: Aux[AddRequest, AddResponse] =
new Processable[AddRequest] {
type Out = AddResponse
def apply(in: AddRequest): AddResponse = AddResponse(in.x + in.y)
}
}
And now you can define process using this type class:
def process[I](in: I)(implicit p: Processable[I]): p.Out = p(in)
Which works as desired (note the appropriate static types):
scala> val res: ToUppercaseResponse = process(ToUppercaseRequest("foo"))
res: ToUppercaseResponse = ToUppercaseResponse(FOO)
scala> val res: AddResponse = process(AddRequest(0, 1))
res: AddResponse = AddResponse(1)
But it doesn't work on arbitrary types:
scala> process("whatever")
<console>:14: error: could not find implicit value for parameter p: Processable[String]
process("whatever")
^
You don't even have to use a path dependent type (you should be able just to have two type parameters on the type class), but it makes using process a little nicer if e.g. you have to provide the type parameter explicitly.
Update: everything above assumes that you don't want to change your case class signatures (which definitely isn't necessary). If you are willing to change them, though, you can do this a little more concisely:
trait Input[Out] {
def computed: Out
}
case class AddRequest(x: Int, y: Int) extends Input[AddResponse] {
def computed: AddResponse = AddResponse(x + y)
}
case class AddResponse(sum: Int)
case class ToUppercaseRequest(str: String) extends Input[ToUppercaseResponse] {
def computed: ToUppercaseResponse = ToUppercaseResponse(str.toUpperCase)
}
case class ToUppercaseResponse(upper: String)
def process[O](in: Input[O]): O = in.computed
And then:
scala> process(AddRequest(0, 1))
res9: AddResponse = AddResponse(1)
scala> process(ToUppercaseRequest("foo"))
res10: ToUppercaseResponse = ToUppercaseResponse(FOO)
Which kind of polymorphism (parametric or ad-hoc) you should prefer is entirely up to you. If you want to be able to describe a mapping between arbitrary types, use a type class. If you don't care, or actively don't want this operation to be available for arbitrary types, using subtyping.
You can define a common trait for Requests, and a common trait for Responses where the request type is defined for specific response type:
trait Request[R <: Response]
trait Response
case class AddRequest(x: Int, y: Int) extends Request[AddResponse]
case class AddResponse(sum: Int) extends Response
case class ToUppercaseRequest(str: String) extends Request[ToUppercaseResponse]
case class ToUppercaseResponse(upper: String) extends Response Response[ToUppercaseRequest]
Then, process signature would be:
def process[A <: Request[B], B <: Response](req: A): B
When you call process, you'll have to explicitly define the types so that the returned type is what you expect it to be - it can't be inferred specifically enough:
val r1: AddResponse = process[AddRequest, AddResponse](AddRequest(2, 3))
val r2: ToUppercaseResponse = process[ToUppercaseRequest, ToUppercaseResponse](ToUppercaseRequest("aaa"))
Thank you in advance for your help
I have 2 functions that I am trying to compose via Kleisli arrows. The functions accept String and produce FreeC. The kleisli arrows are created without an issue but the compiler is complaining that it cannot find. I will cut out some of the code for simplicity:
import scalaz._
import Scalaz._
import Free.FreeC
import Free._
import Kleisli._
trait AppCompose {
def lift[F[_], G[_], A](fa: F[A])(implicit I: Inject[F, G]): FreeC[G, A] =
Free.liftFC(I.inj(fa))
}
object BigBrother {
sealed trait Sensor[A]
case class Log(log: String) extends Sensor[Unit]
case class Filter(log: String) extends Sensor[String]
case class Secure(log: String) extends Sensor[String]
}
import BigBrother.Sensor
class BigBrother[F[_]](implicit I: Inject[Sensor,F]) extends AppCompose {
import BigBrother._
type FreeString[A] = FreeC[F,String]
def log(log: String) = lift(Log(log))
def filter(log: String) = lift(Filter(log))
def secure(log: String) = lift(Secure(log))
def filterAndSecure(phrase: String) = for {
f <- filter(phrase)
s <- secure(f)
} yield s
// kleisli composition attempt - alternative to filterAndSecure
val fk = kleisli[FreeString, String, String](filter _)
val sk = kleisli[FreeString, String, String](secure _)
val fAndS = fk >=> sk // this is where we have a compilation issue
}
For some reason what i get is this compilation error:
could not find implicit value for parameter b: scalaz.Bind[FreeString]
[error] val fAndS = sk >=> fk
feels like the implicit should be resolved since FreeC in a monad instance that implements a Bind trait and i am importing all of the Free implicit instances via import Free._
what am I missing here?
Thank you in advance!
Thank you Travis for your help. Bad type declaration was actually one of the culprits. With some help from the scalaz community via google groups and some tinkering here is the answer:
class BigBrother[F[_]](implicit I: Inject[Sensor,F]) extends AppCompose {
import BigBrother._
def log(log: String) = lift(Log(log))
def filter(log: String) = lift(Filter(log))
def secure(log: String) = lift(Secure(log))
def filterAndSecure(phrase: String) = for {
f <- filter(phrase)
s <- secure(f)
} yield s
type CoyoF[A] = Coyoneda[F, A]
type FreeCoF[A] = Free[CoyoF,A]
implicit val MonadFreeSensor = Free.freeMonad[FreeCoF]
// kleisli composition attempt - alternative to filterAndSecure
val fk = kleisli[FreeCoF, String, String](filter _)
val sk = kleisli[FreeCoF, String, String](secure _)
val fAndS = fk >=> sk
}
key is the correct type declaration and providing the type class monad instance for FreeCoF implicit val MonadFreeSensor = Free.freeMonad[FreeCoF]
What I try to do is to come up with a case class which I can use in pattern matching which has exactly one field, e.g. an immutable set. Furthermore, I would like to make use of functions like map, foldLeft and so on which should be passed down to the set. I tried it as in the following:
case class foo(s:Set[String]) extends Iterable[String] {
override def iterator = s.iterator
}
Now if I try to make use of e.g. the map function, I get an type error:
var bar = foo(Set() + "test1" + "test2")
bar = bar.map(x => x)
found : Iterable[String]
required: foo
bar = bar.map(x => x)
^
The type error is perfectly fine (in my understanding). However, I wonder how one would implement a wrapper case class for a collection such that one can call map, foldLeft and so on and still receive an object of the case class. Would one need to override all these functions or is there some other way around?
Edit
I'm inclined to accept the solution of Régis Jean-Gilles which works for me. However, after Googling for hours I found another interesting Scala trait named SetProxy. I couldn't find any trivial examples so I'm not sure if this trait does what I want:
come up with a custom type, i.e. a different type than Set
the type must be a case class (we want to do pattern matching)
we need "delegate" methods map, foldLeft and so on which should pass the call to our actual set and return the resulting set wrapped arround in our new type
My first idea was to extend Set but my custom type Foo already extends another class. Therefore, the second idea was to mixin the trait Iterable and IterableLike. Now I red about the trait SetProxy which made me think about which is "the best" way to go. What are your thoughts and experiences?
Since I started learning Scala three days ago, any pointers are highly appreciated!
Hmm this sounds promissing to me but Scala says that variable b is of type Iterable[String] and not of type Foo, i.e. I do not see how IterableLike helps in this situation
You are right. Merely inheriting from IterableLike as shown by mpartel will make the return type of some methods more precise (such as filter, which will return Foo), but for others such as map of flatMap you will need to provide an appopriate CanBuildFrom implicit.
Here is a code snippet that does just that:
import collection.IterableLike
import collection.generic.CanBuildFrom
import collection.mutable.Builder
case class Foo( s:Set[String] ) extends Iterable[String] with IterableLike[String, Foo] {
override def iterator = s.iterator
override protected[this] def newBuilder: scala.collection.mutable.Builder[String, Foo] = new Foo.FooBuilder
def +(elem: String ): Foo = new Foo( s + elem )
}
object Foo {
val empty: Foo = Foo( Set.empty[String] )
def apply( elems: String* ) = new Foo( elems.toSet )
class FooBuilder extends Builder[String, Foo] {
protected var elems: Foo = empty
def +=(x: String): this.type = { elems = elems + x; this }
def clear() { elems = empty }
def result: Foo = elems
}
implicit def canBuildFrom[T]: CanBuildFrom[Foo, String, Foo] = new CanBuildFrom[Foo, String, Foo] {
def apply(from: Foo) = apply()
def apply() = new FooBuilder
}
}
And some test in the repl:
scala> var bar = Foo(Set() + "test1" + "test2")
bar: Foo = (test1, test2)
scala> bar = bar.map(x => x) // compiles just fine because map now returns Foo
bar: Foo = (test1, test2)
Inheriting IterableLike[String, Foo] gives you all those methods such that they return Foo. IterableLike requires you to implement newBuilder in addition to iterator.
import scala.collection.IterableLike
import scala.collection.mutable.{Builder, SetBuilder}
case class Foo(stuff: Set[String]) extends Iterable[String] with IterableLike[String, Foo] {
def iterator: Iterator[String] = stuff.iterator
protected[this] override def newBuilder: Builder[String, Foo] = {
new SetBuilder[String, Set[String]](Set.empty).mapResult(Foo(_))
}
}
// Test:
val a = Foo(Set("a", "b", "c"))
val b = a.map(_.toUpperCase)
println(b.toList.sorted.mkString(", ")) // Prints A, B, C
I want to create an enity system with some special properties, based on Scala traits.
The main idea is this: all components are traits that inherit from the common trait:
trait Component
trait ComponentA extends Component
sometimes, in case of a more complex hierarchy and inter-dependant components it can get like this:
trait ComponentN extends ComponentM {
self: ComponentX with ComponentY =>
var a = 1
var b = "hello"
}
and so on. I have come to the conclusion that the data relevant to each component should be contained in itself and not in some storage inside an Entity or elsewhere because of the speed of the access. As a side note - that is also why everything is mutable, so there is no need in thinking about immutability.
Then Entities are created, mixing in the traits:
class Entity
class EntityANXY extends ComponentA
with ComponentN
with ComponentX
with ComponentY
Here all is fine, however I do have a special requirement that I do not know how to fulfill with the code. The requirement is this:
Each trait must provide an encoding method(?) that facilitates collection of the trait-related data in a universal form, for example in a form of a JSON or a Map like Map("a" -> "1", "b" -> "hello") and a decoding method to translate such a map, if received, back into the trait-related variables. Also: 1) all the encoding and decoding methods of all the mixed-in traits are called in a bunch, in an arbitrary order by Entity's methods encode and decode(Map) and 2) should be made available to be called separately by specifying a trait type, or better, by a string parameter like decode("component-n", Map).
It is not possible to use methods with the same name as they will be lost due to shadowing or overriding. I can think of a solution, where all the methods are stored in a Map[String, Map[String, String] => Unit] for decode and Map[String, () => Map[String, String]] for encode in every entity. This would work - the by-name as well as a bunch call would certainly be available. However, this will result in storing the same information in every entity which is unacceptable.
It is also possible to store these maps in a companion object so that it is not duplicated anywhere and call the object's encode and decode method with an extra parameter denoting a particular instance of the entity.
The requirement may seem strange, but it is necessary because of the required speed and modularity. All of these solutions are clumsy and i think there is a better and idiomatic solution in Scala, or maybe I am missing some important architectural pattern here. So is there any simpler and more idiomatic approach than the one with the companion object?
EDIT: I think that aggregation instead of inheritance could probably resolve these problems but at a cost of not being able to call methods directly on an entity.
UPDATE: Exploring the pretty promising way proposed by Rex Kerr, I have stumbled upon something that hinders. Here is the test case:
trait Component {
def encode: Map[String, String]
def decode(m: Map[String, String])
}
abstract class Entity extends Component // so as to enforce the two methods
trait ComponentA extends Component {
var a = 10
def encode: Map[String, String] = Map("a" -> a.toString)
def decode(m: Map[String, String]) {
println("ComponentA: decode " + m)
m.get("a").collect{case aa => a = aa.toInt}
}
}
trait ComponentB extends ComponentA {
var b = 100
override def encode: Map[String, String] = super.encode + ("b" -> b.toString)
override def decode (m: Map[String, String]) {
println("ComponentB: decoding " + m)
super.decode(m)
m.get("b").foreach{bb => b = bb.toInt}
}
}
trait ComponentC extends Component {
var c = "hey!"
def encode: Map[String, String] = Map("c" -> c)
def decode(m: Map[String, String]) {
println("ComponentC: decode " + m)
m.get("c").collect{case cc => c = cc}
}
}
trait ComponentD extends ComponentB with ComponentC {
var d = 11.6f
override def encode: Map[String, String] = super.encode + ("d" -> d.toString)
override def decode(m: Map[String, String]) {
println("ComponentD: decode " + m)
super.decode(m)
m.get("d").collect{case dd => d = dd.toFloat}
}
}
and finally
class EntityA extends ComponentA with ComponentB with ComponentC with ComponentD
so that
object Main {
def main(args: Array[String]) {
val ea = new EntityA
val map = Map("a" -> "1", "b" -> "3", "c" -> "what?", "d" -> "11.24")
println("BEFORE: " + ea.encode)
ea.decode(map)
println("AFTER: " + ea.encode)
}
}
which gives:
BEFORE: Map(c -> hey!, d -> 11.6)
ComponentD: decode Map(a -> 1, b -> 3, c -> what?, d -> 11.24)
ComponentC: decode Map(a -> 1, b -> 3, c -> what?, d -> 11.24)
AFTER: Map(c -> what?, d -> 11.24)
The A and B components are not influenced, being cut-off by the inheritance resolution. So this approach is only applicable in certain hierarchy cases. In this case we see that the ComponentD has shadowed everything else. Any comments are welcomed.
UPDATE 2: I place the comment that answers this problem here, for better reference: "Scala linearizes all the traits. There should be a supertrait of everything which will terminate the chain. In your case, that means that C and A should still call super, and Component should be the one to terminate the chain with a no-op." – Rex Kerr
Travis had an essentially correct answer; not sure why he deleted it. But, anyway, you can do this without too much grief as long as you're willing to make your encoding method take an extra parameter, and that when you decode you're happy to just set mutable variables, not create a new object. (Complex trait-stacking effectively-at-runtime ranges from difficult to impossible.)
The basic observation is that when you chain traits together, it defines a hierarchy of superclass calls. If each of these calls takes care of the data in that trait, you'd be set, as long as you can find a way to get all that data back. So
trait T {
def encodeMe(s: Seq[String]): Seq[String] = Seq()
def encode = encodeMe(Seq())
}
trait A extends T {
override def encodeMe(s: Seq[String]) = super.encodeMe(s) :+ "A"
}
trait B extends T {
override def encodeMe(s: Seq[String]) = super.encodeMe(s) :+ "B"
}
Does it work?
scala> val a = new A with B
a: java.lang.Object with A with B = $anon$1#41a92be6
scala> a.encode
res8: Seq[String] = List(A, B)
scala> val b = new B with A
b: java.lang.Object with B with A = $anon$1#3774acff
scala> b.encode
res9: Seq[String] = List(B, A)
Indeed! Not only does it work, but you get the order for free.
Now we need a way to set variables based on this encoding. Here, we follow the same pattern--we take some input and just go up the super chain with it. If you have very many traits stacked on, you may want to pre-parse text into a map or filter out those parts applicable to the current trait. If not, just pass on everything to super, and then set yourself after it.
trait T {
var t = 0
def decode(m: Map[String,Int]) { m.get("t").foreach{ ti => t = ti } }
}
trait C extends T {
var c = 1
override def decode(m: Map[String,Int]) {
super.decode(m); m.get("c").foreach{ ci => c = ci }
}
}
trait D extends T {
var d = 1
override def decode(m: Map[String,Int]) {
super.decode(m); m.get("d").foreach{ di => d = di }
}
}
And this too works just like one would hope:
scala> val c = new C with D
c: java.lang.Object with C with D = $anon$1#549f9afb
scala> val d = new D with C
d: java.lang.Object with D with C = $anon$1#548ea21d
scala> c.decode(Map("c"->4,"d"->2,"t"->5))
scala> "%d %d %d".format(c.t,c.c,c.d)
res1: String = 5 4 2