I've got the following helper method in my project:
def close(c: Closeable) {
Option(c).foreach(s => Try(s.close))
}
I've got some classes that have a close method but do not implement Closeable. If I change the helper method to use structural types I can still use it on these classes:
def close(c: {def close()}) {
Option(c).foreach(s => Try(s.close))
}
However this introduces use of reflection which is something that I'd like to avoid in runtime.
Is there a way to use something similar to structural typing without inducing runtime reflection?
I.e in the same way Shapeless allows generic access to fields, maybe implicit parameters + macros could be used to access methods in the same way?
Use traits to implement the typeclass pattern.
When I wrote my original solution it was a bit rough round the edges as I assumed a quick search for convert structural bounds to context bounds would pull up better explanations than I could write. That doesn't seem to be the case. Below is a compiling solution.
object Closeables {
trait MyCloseable[A] {
def myClose(a: A): Unit
}
object MyCloseable {
implicit object MyCanBeClosed extends MyCloseable[CanBeClosed] {
def myClose(c: CanBeClosed) = c.nonStandardClose()
}
}
}
class CanBeClosed {
def nonStandardClose(): Unit = println("Closing")
}
import Closeables._
object Test extends App {
def functionThatCloses[A: MyCloseable](a: A) {
implicitly[MyCloseable[A]].myClose(a)
}
def functionThatClosesExplicit[A](a: A)(implicit ev: MyCloseable[A]) {
ev.myClose(a)
}
val c = new CanBeClosed
functionThatCloses(c)
functionThatClosesExplicit(c)
functionThatCloses(c)(MyCloseable.MyCanBeClosed)
functionThatClosesExplicit(c)(MyCloseable.MyCanBeClosed)
}
For each type of class that can be accepted by functionThatCloses you must define and implicit object in MyCloseables.
The compiler looks at the context bound in functionThatCloses and converts it to a function with the definition of functionThatClosesExplicitly.
The compiler than 'finds' the implicit 'evidence' in the definition from the MyCloseables object and uses that.
Related
Imagine I have a service:
class ServiceA(serviceB: ServiceB) {
import Extractor._
def send(typeA: A) = serviceB.send(typeA.extract)
}
object Extractor {
implicit class Extractor(type: A) {
def extract = ???
}
}
I want the extract method to be an implicitly defined because it doesn't directly relate to A type/domain and is a solution specific adhoc extension.
Now I would like to write a very simple unit test that confirms that serviceB.send is called.
For that, I mock service and pass a mocked A to send. Then I could just assert that serviceB.send was called with the mocked A.
As seen in the example, the send method also does some transformation on typeA parameter so I would need to mock extract method to return my specified value. However, A doesn't have extract method - it comes from the implicit class.
So the question is - how do I mock out the implicit class as in the example above as imports are not first class citizens.
If you want to specify a bunch of customised extract methods, you can do something like this:
sealed trait Extractor[T] {
// or whatever signature you want
def extract(obj: T): String
}
object Extractor {
implicit case object IntExtractor extends Extractor[Int] {
def extract(obj: Int): String = s"I am an int and my value is $obj"
}
implicit case object StringExtractor extends Extractor[String] {
def extract(obj: String): String = s"I am "
}
def apply[A : Extractor](obj: A): String = {
implicitly[Extractor[A]].extract(obj)
}
}
So you have basically a sealed type family that's pre-materialised through case objects, which are arguably only useful in a match. But that would let you decouple everything.
If you don't want to mix this with Extractor, call them something else and follow the same approach, you can then mix it all in with a context bound.
Then you can use this with:
println(Extractor(5))
For testing, simply override the available implicits if you need to. A bit of work, but not impossible, you can simply control the scope and you can spy on whatever method calls you want.
e.g instead of import Extractor._ have some other object with test only logic where you can use mocks or an alternative implementation.
We've got several types of resources and we wanted to make a method to check if a resource is healthy or not. Given that the type of resources are very heterogeneous we didn't want to use standard subclassing and we decided to use a typeclass:
trait CanHealthCheck[T] {
def isHealthy(t: T): Boolean
}
We also have a utility method to be able to check if a given resource is alive/healthy or not
object LivenessChecker {
def isAlive[T](t: T)(implicit canHealthCheck: CanHealthCheck[T]): Boolean = {
canHealthCheck.isHealthy(t)
}
}
We've got a repository layer to access to the data. We would like to express the idea that a given abstract repository must be "health checkable" but to leave the implementation details to the subclasses implementing the trait:
trait UserRepository {
def findSomeUser(): User = ???
implicit def isHealthCheckable: CanHealthCheck[UserRepository]
}
The problem arises when we want to subclass UserRepository with a particular implementation, given that CanHealthCheck is not covariant on the type T.
class DbUserRepository extends UserRepository {
def ping: Boolean = ???
override implicit val isHealthCheckable: CanHealthCheck[UserRepository] =
new CanHealthCheck[DbUserRepository] {
def isHealthy(db: DbUserRepository) = db.ping
}
}
And this is an example of some dummy function that acts on the abstract repository while trying to check if the repository is alive:
def someDummyFunction(userRepository: UserRepository) = {
if(LivenessChecker.isAlive(userRepository)) // This won't compile
userRepository.findSomeUser()
}
The idea is that our application uses the UserRepository trait and not the implementation, and thus we cannot check whether the repository is alive or not. How can we continue using the repository abstraction layer and be able to check if a given (abstract) repository is alive? Is the typeclass pattern the correct pattern to use here?
There is something a bit fishy with isHealthCheckable inside UserRespository. The isHealthy method, when called, would have two instances of UserRepository available: of course, the one passed as the t argument, but also, the UserRepository.this of the enclosing instance.
This is a sign of something wrong. Either the method should be written somewhere else, so that it does not get enclosing this, or it should not get the argument
That second option is consistent with using UserRepository the object-oriented, subtyping way. Also, it is consistent with your idea that every UserRepository must be heath-checkable. Just do
trait UserRepository {
...
def isHealty: Boolean
}
It is fine to call that directly, userDirectory.isHealthy. But you can then also easily implement the type class:
object UserRepository {
implicit val canHealthCheck = new CanHealthCheck[UserRepository] {
def isHealthy(repository: UserRepository) = repository.IsHealthy
}
}
also note that it was not clear at all how the implicit instance method would have come into the implicit scope. With the companion object, it works fine.
Use "type bounds".
I couldn't test this, but to get the code to compile, you could do something like:
class DbUserRepository[U <: UserRepository] extends UserRepository {
def ping: Boolean = ???
implicit val isHealthCheckable: CanHealthCheck[U] =
new CanHealthCheck[U] {
def isHealthy(db: U) = db.ping
}
}
I am using a library which has a class that has a generic type that can be quite complicated. I need to write a method that takes a parameter with the generic type that a val of the library class has, and I would like to avoid having to write out the type in the method signature. I thought I might be able to create an implicit class which adds a type to the val that I could use in the method signature, kind of like:
// This comes from a library and can't be changed
case class LibraryClass[A](a: A)
//----------------------------------
object MyCode {
val thing = LibraryClass(3)
implicit class LibraryClassWithType[A](lc: LibraryClass[A]) {
type TheType = A
}
def doStuff(something: thing.TheType): Unit = {
println(something)
}
}
This does not compile (TheType is not a member of LibraryClass). But if I wrap it in the class myself, it works
val thingWithType = LibraryClassWithType(thing)
def doStuff(something: thingWithType.TheType): Unit = {
println(something)
}
Is there something I am missing that will make this work, or is this kind of implicit conversion not valid Scala?
I haven't been able to do this sort of thing with implicits, but I have had to do something similar where I just instantiated these sorts of type holders:
case class LibraryClass[A](a: A)
object MyCode {
val thing = LibraryClass(3)
class HigherTypeHolder[A,F[A]](a: F[A]) {
type AT = A
}
val th = new HigherTypeHolder(thing)
def doStuff(something: th.AT): Unit = {
println(something)
}
}
You can do what (I think) you want like this:
implicit val thing = LibraryClass(3)
def doStuff[A](something: A)(implicit lc: LibraryClass[A])
What I don't understand is why this needs to be so complicated. Why not for example stick with your second approach, without implicits, that works, or why not just do
def doStuff[A](something: A) to begin with?
I am trying to get my head around on what is best way to code this implementation. To give you example, here is my DAO handler code looks like
trait IDAOHandler[+T] {
def create[U <: AnyRef: Manifest](content: U): Try[String]
}
class MongoDAOHAndler extends IDAOHandler[+T]...
So I am creating actor that will handle all my persistence task that includes serializing the content and updating MongoDB database.
So I am using akka and the trick is in receive method, how do i handle generics type parameter. Even though my actor code is non-generic, but the messages it is going to receive will be generic type and based on content type in createDAO I was planning to get appropriate DAO handler (described aboe) and invoke the method.
case class createDAO[T](content: T) (implicit val metaInfo:TypeTag[T])
class CDAOActor(daofactory: DAOFactory) extends BaseActor {
def wrappedReceive = {
case x: createDAO[_] => pmatch(x)
}
def pmatch[A](c: createDAO[A]) {
//getting dao handler which will not work because it needs manifest
}
}
Let me know if there are any other ways to re-write this implementation.
You might already know this, but a little background just to be sure: In Scala (and Java) we have what is called type erasure, this means that the parametric types are used to verify the correctness of the code during compile time but is then removed (and "does not give a runtime cost", http://docs.oracle.com/javase/tutorial/java/generics/erasure.html). Pattern matching happens during runtime so the parametric types are already erased.
The good news is that you can make the Scala compiler keep the erased type by using TypeTag like you have done in your case class or ClassTag which contains less information but also keeps the erased type. You can get the erased type from the method .erasure (.runtimeClass in Scala 2.11) which will return the Java Class of the T type. You still wont be able to use that as the type parameter for a method call as that again happens compile time and you are now looking at that type in runtime, but what you can do is to compare this type during runtime with if/else or patternmatching.
So for example you could implement a method on your daofactory that takes a Class[_] parameter and returns a DAO instance for that class. In pmatch you would then take the erased type out of the tag and pass on to it.
Here is some more info about the tags, why they exist and how they work:
http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html
I took a bit different approach, kind of dispatcher pattern, so here is the revised code
trait IDAOProcess
{
def process(daofactory:IDAOFactory,sender:ActorRef)
}
case class createDAO[T <: AnyRef : Manifest](content:T) (implicit val metaInfo:TypeTag[T]) extends IDAOProcess
{
def process(daofactory:IDAOFactory,sender:ActorRef)
{
for ( handler <- daofactory.getDAO[T] )
{
handler.create(content)
}
}
}
class DAOActor(daofactory:IDAOFactory) extends BaseActor
{
def wrappedReceive =
{
case x:IDAOProcess =>
{
x.process(daofactory,sender)
}
}
}
I'm having trouble finding an elegant way of designing a some simple classes to represent HTTP messages in Scala.
Say I have something like this:
abstract class HttpMessage(headers: List[String]) {
def addHeader(header: String) = ???
}
class HttpRequest(path: String, headers: List[String])
extends HttpMessage(headers)
new HttpRequest("/", List("foo")).addHeader("bar")
How can I make the addHeader method return a copy of itself with the new header added? (and keep the current value of path as well)
Thanks,
Rob.
It is annoying but the solution to implement your required pattern is not trivial.
The first point to notice is that if you want to preserve your subclass type, you need to add a type parameter. Without this, you are not able to specify an unknown return type in HttpMessage
abstract class HttpMessage(headers: List[String]) {
type X <: HttpMessage
def addHeader(header: String):X
}
Then you can implement the method in your concrete subclasses where you will have to specify the value of X:
class HttpRequest(path: String, headers: List[String])
extends HttpMessage(headers){
type X = HttpRequest
def addHeader(header: String):HttpRequest = new HttpRequest(path, headers :+header)
}
A better, more scalable solution is to use implicit for the purpose.
trait HeaderAdder[T<:HttpMessage]{
def addHeader(httpMessage:T, header:String):T
}
and now you can define your method on the HttpMessage class like the following:
abstract class HttpMessage(headers: List[String]) {
type X <: HttpMessage
def addHeader(header: String)(implicit headerAdder:HeaderAdder[X]):X = headerAdder.add(this,header) }
}
This latest approach is based on the typeclass concept and scales much better than inheritance. The idea is that you are not forced to have a valid HeaderAdder[T] for every T in your hierarchy, and if you try to call the method on a class for which no implicit is available in scope, you will get a compile time error.
This is great, because it prevents you to have to implement addHeader = sys.error("This is not supported")
for certain classes in the hierarchy when it becomes "dirty" or to refactor it to avoid it becomes "dirty".
The best way to manage implicit is to put them in a trait like the following:
trait HeaderAdders {
implicit val httpRequestHeaderAdder:HeaderAdder[HttpRequest] = new HeaderAdder[HttpRequest] { ... }
implicit val httpRequestHeaderAdder:HeaderAdder[HttpWhat] = new HeaderAdder[HttpWhat] { ... }
}
and then you provide also an object, in case user can't mix it (for example if you have frameworks that investigate through reflection properties of the object, you don't want extra properties to be added to your current instance) (http://www.artima.com/scalazine/articles/selfless_trait_pattern.html)
object HeaderAdders extends HeaderAdders
So for example you can write things such as
// mixing example
class MyTest extends HeaderAdders // who cares about having two extra value in the object
// import example
import HeaderAdders._
class MyDomainClass // implicits are in scope, but not mixed inside MyDomainClass, so reflection from Hiberante will still work correctly
By the way, this design problem is the same of Scala collections, with the only difference that your HttpMessage is TraversableLike. Have a look to this question Calling map on a parallel collection via a reference to an ancestor type