Reputation: 15
I have been running an algorithm that is designed to take a postfix expression and return the evaluated value.
To carry out the individual functions, I designed an array of lists that basically functions as:
string representation of operation: String, values taken (-1): Integer, function describing what to do: Float I wrote this as
val functions = arrayOf<List<Any>>(
listOf("+",1,fun (i:List<Float>):Float = i[0] + i[1]),
listOf("-",1,fun (i:List<Float>):Float = i[0] - i[1]),
// etc (rest of them are currently commented out)
)
On compiling this I got the error:
app\src\main\kotlin\KotlinApp.kt: (48, 34): Expression 'f[2]' of type 'Any' cnvoked as a function. The function 'invoke()' is not found
This is referring to how I call f[2](temp:List<Float>)
at element f
of the array.
I recognise the error here is how as my lists are of type any
, the functions inside them aren't assumed to be functions by the compiler. But as I obviously can't cast these to a function, I'm at a loss.
I have tried using lambda expressions instead of anonymous single-expression functions, i.e.
val functions = arrayOf<List<Any>>(
listOf("+",1,i : List<Float> -> i[0] + i[1],
listOf("-",1,i : List<Float> -> i[0] - i[1]),
// etc
)
But as I'm not particularly familiar with lambdas, I don't know whether I did it correctly.
Any help would be appreciated
Full KotlinApp.kt file:
package gradleMain;
import org.shuntingyard.sya
import kotlin.math.*
import java.util.Stack
class KotlinApp {
val functions = arrayOf<List<Any>>(
listOf("+",1,fun (i:List<Float>):Float = i[0] + i[1]),
listOf("-",1,fun (i:List<Float>):Float = i[0] - i[1]),
// listOf("*",1,{ i : List<Float> -> i[0]*i[1]}),
// listOf("/",1,{ i : List<Float> -> i[0]/i[1]}),
// listOf("^",1,{ i : List<Float> -> i[0].pow(i[1])}),
// listOf("sin",0,{ i : List<Float> -> sin(i[0])}),
// listOf("cos",0,{ i : List<Float> -> cos(i[0])}),
// listOf("tan",0,{ i : List<Float> -> tan(i[0])}),
// listOf("asin",0,{ i : List<Float> -> asin(i[0])}),
// listOf("acos",0,{ i : List<Float> -> acos(i[0])}),
// listOf("atan",0,{ i : List<Float> -> atan(i[0])}),
// listOf("sinh",0,{ i : List<Float> -> sinh(i[0])}),
// listOf("cosh",0,{ i : List<Float> -> cosh(i[0])}),
// listOf("tanh",0,{ i : List<Float> -> tanh(i[0])}),
// listOf("fact",0, /* TODO: Need to incorporate gamma function, once established integrals" */ ),
// listOf("int",1,/* TODO: Incorporate integrals */),
// listOf("dif",1,/* TODO: Incorporate differentiation */),
// listOf("log",0,{ i : List<Float> -> log(i[0], 10F)}),
// listOf("ln",0,{ i : List<Float> -> ln(i[0])}),
// listOf("sqrt",0,{ i : List<Float> -> i[0].pow(0.5F)}),
// listOf("sec",0,{ i : List<Float> -> 1/cos(i[0])}),
// listOf("csc",0,{ i : List<Float> -> 1/sin(i[0])}),
// listOf("cot",0,{ i : List<Float> -> 1/tan(i[0])})
)
fun calculate(eq:List<String>):Float{ // takes the rpn of the equation and returns the result
var operand: Stack<String> = Stack()
var temp = listOf<Float>()
for(i in eq){
var n = false
for(f in functions){
if(i==f[0]){
val x: Int = f[1].toString().toInt()
for(j in 0..x){
temp+=operand.pop().toFloat()
}
operand.push(f[2](temp))
n = true
break;
}
}
if(!n){ // when i isnt an operator/function
operand.push(i)
}
}
val result = operand.peek().toFloat()
return result
}
}
fun main(){
val k = KotlinApp()
val e = sya(" 3 + 7 - 2") // runs shunting yard algorithm on equation
val f = k.calculate(e)
println("$f")
}
Upvotes: 0
Views: 51
Reputation: 3437
Note: I didnt look at your logic. Helping just to solve your problem of accessing function. So here is the thing.
Calculate function:
fun calculate(eq:List<String>):Float{ // takes the rpn of the equation and returns the result
var operand: Stack<String> = Stack()
val temp = mutableListOf<Float>()
for (i in eq){
var n = false
for (f in functions){
if (i == f.first){
val x: Int = f.second.toString().toInt()
for(j in 0..x){
temp+=operand.pop().toFloat()
}
operand.push(f.third(temp).toString()) // Float to String
n = true
break
}
}
if(!n){ // when i isnt an operator/function
operand.push(i)
}
}
val result = operand.peek().toFloat()
return result
}
Custom type of the function:
typealias MyFunctionType = (a:List<Float>) -> Float
List of functions:
val functions = arrayListOf<Triple<String,Int,MyFunctionType>>(
Triple("+",1,fun (i:List<Float>):Float = i[0] + i[1]),
Triple("-",1,fun (i:List<Float>):Float = i[0] + i[1])
)
Upvotes: 1