'I want to create new type of simple operator class kotlin
What I want to do is save operator with number in list and evaluate it after pushing it to list
need 2 types of operator Add and Multiply
Plus(x) (x is number)
Multiply(x) (x is number)
lis = [ Plus(3), Multiply(3), Plus(4), Multiply(2) ]
When Plus Start
lis.fold(0) { total, operator -> blar..blar }
-> (((0 + 3) * 3) + 4) * 2
When Multiply Start
lis.fold(1) { total, operator -> blar..blar }
how to declare abstract operator
I think Plus and Multiply Operator has one infix function something like below
infix fun <T>evaluate(value: T): T = this+value
or
infix fun <T>evaluate(value: T): T = this*value
Solution 1:[1]
In order to allow the distinction whether to use a 0 or a 1 depending on the first element, you could define your operation with an identity element:
open class Operation(
val op: (Double) -> Double,
val identity: Double,
)
class Plus(operand: Double) : Operation({ it + operand }, 0.0)
class Multiply(operand: Double) : Operation({ it * operand }, 1.0)
Then, the application of all elements in a list can be defined as:
fun List<Operation>.apply(): Double = if (isEmpty()) 1.0 else
fold(first().identity) { total, operation -> operation.op(total) }
The application of all elements as in your example can then be invoked using apply:
val lis = listOf(Plus(3.0), Multiply(3.0), Plus(4.0), Multiply(2.0))
lis.apply()
If you do not like that an operator is defined and applied via its property op (e.g. the application of Plus(3.0) to a value 5.0 is done by Plus(3.0).op(5.0)), we can alternatively define Operation and the concrete subclasses in the following way:
abstract class Operation(val identity: Double) {
abstract operator fun invoke(x: Double): Double
}
class Plus(private val operand: Double) : Operation(0.0) {
override fun invoke(x: Double): Double = x + operand
}
class Multiply(private val operand: Double) : Operation(1.0) {
override fun invoke(x: Double): Double = x * operand
}
Then, the apply function would also change:
fun List<Operation>.apply(): Double = if (isEmpty()) 1.0 else
fold(first().identity) { total, operation -> operation(total) }
which might look a bit more intuitive.
The invoke operator allows us to apply the Operation like a function to a value, e.g. you can also write Plus(3.0)(5.0) to apply _ + 3.0 to the value 5.0.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
