Is there a type class for singleton Apply[A] - singleton

What is a typeclass for something like this:
trait SingletonApply[A <: AnyRef] {
def apply(x: A): x.type
}
Is there something like this already in Cats or Scalaz?

Related

Generics in Objects

I have a question about sealed class, generics and object.
Let's say I would like to model something like 3 finite cases with a sealed class something like this:
sealed class ChangeState<S> {
fun reduceState(state: S): S
}
data class SetState<S>(val newState: S) : ChangeState<S>() {
override fun reduce(state: S): S = newState
}
object NoStateChange : ChangeState<Nothing>() { // What do I specify here for ChangeState? Nothing?
override fun reduce(state: Nothing): Nothing {
throw Exception("This should never be called")
}
}
The goal is to provide a convenient way to define NoStateChange in a generic way that it can be used as following:
fun foo(i : Int) : ChangeState<Int> {
return if (i==0)
NoStateChange // Won't compile because return type is ChangeState<Nothing> but expected ChangeState<Int>
else
SetState(i)
}
Is there a way to do that with object and Generics somehow?
As pointed out by #Tenfour04 the issue is that out is needed but reduceState() would require in as well. However, reduceState() can be refactored out of the class hierarchy and moved to an extension function like that:
sealed class ChangeState<out S>
data class SetState<S>(val newState: S) : ChangeState<S>()
object NoStateChange : ChangeState<Nothing>()
fun <S> ChangeState<S>.reduce(state: S): S {
return when (val change = this) {
is SetState -> change.newState
is NoStateChange -> state
}
}

How to call function from generic function without knowing the type?

Is there a way to do the following?:
class Someotherthing
class SomeotherthingDTO
class Something
class SomethingDTO
fun convert(entity: Someotherthing): SomeotherthingDTO = SomeotherthingDTO()
fun convert(entity: Something): SomethingDTO = SomethingDTO()
fun <T, D> generic(entity: T): D {
// TODO: check here if there is convert() that accepts type T?! somehow? reflection? reification? or it will be possible only in the future by using typeclasses (KEEP-87)?
return convert(entity)
}
fun main() {
val x: SomethingDTO = convert(Something())
println(x.toString())
}
Currently, the result is: none of the following can be called with the arguments supplied...
You'll need multiple receviers for this to work (KEEP-87). With those you'll be able to "find" the receivers properly.
Until then what I usually do is to put Converters in a ConverterRegistry to do the conversion like this:
interface Converter<A, B> {
val fromClass: KClass<A>
val toClass: KClass<B>
fun convert(from: A): B
fun convertBack(from: B): A
}
interface ConverterRegistry {
fun <A, B> tryConvert(from: KClass<A>, to: KClass<B>): B?
}

How to get rid of this boilerplate code in this sealed class hierarchy?

Suppose I've got a sealed class hierarchy like that:
sealed class A {
abstract val x: Int
abstract fun copyX(x1: Int): A
}
data class A1(override val x: Int, val s1: String) : A() {
override fun copyX(x1: Int): A {
return this.copy(x = x1)
}
}
data class A2(override val x: Int, val s2: String) : A() {
override fun copyX(x1: Int): A {
return this.copy(x = x1)
}
}
All the data classes have field x and should provide method copyX(x1: Int) to copy all the fields but x and override x with x1. For instance,
fun foo(a: A): A { a.copyX(100) }
The definitions above probably work but the repeating copyX across all the data classes seem very clumsy. How would you suggest get rid of this repeated copyX ?
First, you can implement copyX as an extension (or even A's member) so as to concentrate the code in one place and avoid at least duplicating the copyX function in the sealed class subtypes:
sealed class A {
abstract val x: Int
}
fun A.copyX(x1: Int): A = when (this) {
is A1 -> copy(x = x1)
is A2 -> copy(x = x1)
}
data class A1(override val x: Int, val s1: String) : A()
data class A2(override val x: Int, val s2: String) : A()
If you have a lot of sealed subtypes and all of them are data classes or have a copy function, you could also copy them generically with reflection. For that, you would need to get the primaryConstructor or the function named copy from the KClass, then fill the arguments for the call, finding the x parameter by name and putting the x1 value for it, and putting the values obtained from component1(), component2() etc. calls or leaving the default values for the other parameters. It would look like this:
fun A.copyX(x1: Int): A {
val copyFunction = this::class.memberFunctions.single { it.name == "copy" }
val args = mapOf(
copyFunction.instanceParameter!! to this,
copyFunction.parameters.single { it.name == "x" } to x1
)
return copyFunction.callBy(args) as A
}
This works because callBy allows omitting the optional arguments.
Note that it requires a dependency on kotlin-reflect and works only with Kotlin/JVM. Also, reflection has some performance overhead, so it's not suitable for performance-critical code. You could optimize this by using the Java reflection (this::class.java, getMethod(...)) instead (which would be more verbose) and caching the reflection entities.

How can I create a Factory that produces objects based on a type or a Class object?

In my Kotlin application I have a few entities (and a data class for each of them) and for each entity I have a service object implementing generic Service<T> interface.
I want to create a Factory of services that will return me a proper service based on a parameter which is a type of entity I want to have a service for. In Java I would pass a Class object into the factory which I could obtain from a static context of the entity class eg. Entity.class but I can't do that in Kotlin. How can I create a Factory that will produce me objects based on a type of an entity?
You're looking for KClass:
Say you have the following classes:
abstract class Parent(val name: String)
class ChildA : Parent("A")
class ChildB : Parent("B")
Then your factory may look like this:
fun <T : Any> factory(c: KClass<T>): T {
return c.createInstance()
}
fun main(args: Array<String>) {
val childA = factory(ChildA::class)
val childB = factory(ChildB::class)
println(childA.name) // A
println(childB.name) // B
}
But there's a better way using reified:
inline fun <reified T : Any> factory(): T {
return T::class.createInstance()
}
Then you can call it like this:
val childA = factory<ChildA>()
val childB = factory<ChildB>()
println(childA.name)
println(childB.name)
Note that without using reified we couldn't do T::class

Scala hierarchy decomposition and type parameters

I have the following class hierarchy.
sealed trait Foo {
val a: String
}
case class Bar1(a: String) extends Foo
case class Bar2(a: String) extends Foo
Now I want to add a convenient method to modify the field a. I need this method to be accessible in the super type Foo and I want to use the .copy method of the case class (because I actually have a lot more fields and it is painful to use the constructor). My first attempt was to use pattern matching :
sealed trait Foo {
val a: String
def withField(b: String) = this match {
case b1: Bar1 => b1.copy(a = b)
case b2: Bar2 => b2.copy(a = b)
}
}
Now I would also like my withField method to return an instance type of the caller, B1 if the method is called by an instance of type B1, B2 if the method is called by an instance of type B2 and Foo if this is all I know. So I thought to myself I might be able to parametrized the method withFieldto serve this purpose. Something like:
sealed trait Foo {
val a: String
def withField[A <: Foo](b: String) = this match {
case b1: Bar1 => b1.copy(a = b)
case b2: Bar2 => b2.copy(a = b)
}
}
but I don't manage to parametried withField with the type of this.
Am I getting completely wrong here ? Should I use a different pattern maybe using override modifier ?
Thanks a lot
Am I getting completely wrong here ? Should I use a different pattern maybe using override modifier ?
Yes. There are two alternatives:
sealed trait Foo {
val a: String
def withField(b: String): Foo
}
case class Bar1(a: String) extends Foo {
// return types are covariant, and Bar1 is subtype of Foo,
// so this is legal
def withField(b: String): Bar1 = ...
}
or
sealed trait Foo[ThisType <: Foo[ThisType]] {
val a: String
def withField(b: String): ThisType
}
case class Bar1(a: String) extends Foo[Bar1] {
def withField(b: String): Bar1 = ...
}
Note the second is more complex, and should only be used if you actually need it.
EDIT to answer Christian's question:
sealed trait Foo {
type ThisType <: Foo
def withField(b: String): ThisType = (this match {
case b1: Bar1 => b1.copy(a = b)
...
}).asInstanceOf[ThisType]
}
case class Bar1(a: String) extends Foo {
type ThisType = Bar1
}
I don't like it: it needs a cast, actually using it would require dependent method types, and I wouldn't be surprised if it broke down in practice (e.g. because the compiler can't prove foo.ThisType and foo.withField("a").ThisType are the same).