我想创建新类型的简单运算符 class kotlin

I want to create new type of simple operator class kotlin

我想做的是在列表中保存带有数字的运算符 并将其推入列表后对其进行评估

需要两种操作员 加法和乘法

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 }

如何声明抽象运算符

我认为加号和乘号运算符只有一个中缀函数 类似下面

infix fun <T>evaluate(value: T): T = this+value
or
infix fun <T>evaluate(value: T): T = this*value

为了根据第一个元素区分是使用 0 还是 1,您可以使用 identity 元素定义操作:

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)

那么,一个列表中所有元素的应用可以定义为:

fun List<Operation>.apply(): Double = if (isEmpty()) 1.0 else
    fold(first().identity) { total, operation -> operation.op(total) }

然后可以使用 apply:

调用示例中所有元素的应用程序
val lis = listOf(Plus(3.0), Multiply(3.0), Plus(4.0), Multiply(2.0))
lis.apply()

如果您不喜欢通过其 属性 op 定义和应用运算符(例如,将 Plus(3.0) 应用于值 5.0 是通过Plus(3.0).op(5.0)),我们也可以通过以下方式定义 Operation 和具体的子类:

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
}

那么,apply函数也会改变:

fun List<Operation>.apply(): Double = if (isEmpty()) 1.0 else
    fold(first().identity) { total, operation -> operation(total) }

这可能看起来更直观一些。

invoke 运算符允许我们将 Operation 像函数一样应用于值,例如您还可以编写 Plus(3.0)(5.0) 以将 _ + 3.0 应用于值 5.0.