The main problem I found was finding an equivalent operator to the pipeOperator|>
, then i found three potential alternatives:
using .let
using .run
using infix function
Below example was good startup for me to solve my issue:
fun main(args: Array<String>) {
var a = 3
val b: Int = 6
println("Hello World! doubling, then tripling the sume of $a and $b is " +
"${(sumx(a,b)
next ::dbl
next ::trpl
)}")
println("Hello World! doubling, then tripling the sume of $a and $b is " +
"${(sumx(a,b)
.let (::dbl)
.let (::trpl)
)}")
println("Hello World! doubling, then tripling the sume of $a and $b is " +
"${(sumx(a,b)
.run (::dbl)
.run (::trpl)
)}")
println("Hello World! doubling, then tripling the sume of $a and $b is " +
"${(sumx(a,b)
into (::dbl)
into (::trpl)
)}")
}
fun sumx (x: Int, y: Int) : Int = x + y
fun dbl (x: Int): Int = x * 2
fun trpl (x: Int): Int = x * 3
infix fun <T, R> T.next(map : (T) -> R) : R = map(this)
infix fun <T, R> T.into(func: (T) -> R) = func(this)
UPDATE
I Created the gradle project using this command: gradle init --type java-library
Deleted the src/main
and the src/test
folders
Created the src/kotlin
and src/resources
folders
Created my file at src/kotlin/Main.kt
as below:
import kotlin.coroutines.experimental.buildSequence
fun main(args: Array<String>) {
println("Hi, Let's start")
val series = listOf(
30, 21, 29, 31, 40, 48, 53, 47, 37, 39, 31, 29, 17, 9, 20, 24, 27, 35, 41, 38,
27, 31, 27, 26, 21, 13, 21, 18, 33, 35, 40, 36, 22, 24, 21, 20, 17, 14, 17, 19,
26, 29, 40, 31, 20, 24, 18, 26, 17, 9, 17, 21, 28, 32, 46, 33, 23, 28, 22, 27,
18, 8, 17, 21, 31, 34, 44, 38, 31, 30, 26, 32
)
fun initialSeasonalComponents(series: List<Int>, slen: Int): Map<Int, Double> {
val nSeasons = (series.size / slen).toFloat()
val grouped = series.map { it.toFloat() }.chunked(slen)
val seasonAverages = grouped.map { it.average() }
return (0 until slen).associate {
Pair(it, grouped.zip(seasonAverages)
.fold(0.0) { s, (els, av) -> els[it] + s - av }
/ nSeasons)
}
}
println("Seasons Averageß: \n ${initialSeasonalComponents(series, 12)}")
fun initialTrend(series: List<Int>, slen: Int): Double =
series.windowed(slen)
.fold(0) { s, x -> x.last() - x.first() + s }
.toFloat() / slen.toDouble()
println("Initial Trend: \n ${initialTrend(series, 12)}")
fun tripleExponentialSmoothing(series: List<Int>, slen: Int, alpha: Double, beta: Double, gamma: Double, nPreds: Int): Sequence<Double> {
var smooth = 0.0
var trend = 0.0
val seasonals = initialSeasonalComponents(series, 12).toMutableMap()
return buildSequence {
for (i in 0 until (series.size + nPreds)) {
when {
i == 0 -> {
smooth = series.first().toDouble()
trend = initialTrend(series, slen)
yield(series.first().toDouble())
}
i >= series.size -> {
val m = i - series.size + 1
yield((smooth + m * trend) + (seasonals[i % slen] ?: 0.0 /* Need default values because of null safety */))
}
else -> {
val v = series.first().toDouble()
val lastSmooth = smooth
smooth = alpha * (v - (seasonals[i % slen] ?: 0.0)) + (1.0 - alpha) * (smooth + trend)
trend = beta * (smooth - lastSmooth) + (1.0 - beta) * trend
seasonals[i % slen] = gamma * (v - smooth) + (1.0 - gamma) * (seasonals[i % slen] ?: 0.0)
yield(smooth + trend + (seasonals[i % slen] ?: 0.0))
}
}
}
}
}
val f = tripleExponentialSmoothing(series, 12, 0.716, 0.029, 0.993, 24).toList()
val res = f.map {it.format(2)} // used to format the numbers, can be avoided.
println("Forecast: \n $res")
}
fun Double.format(digits: Int) = java.lang.String.format("%.${digits}f", this) // Extension function to format the numbers
The 0.0
is the initial state for the fold
function, { s, (els, av) -> }
is the operation applied to each element, where s is the accumulator and (els, av)
is the current element (in this case an entry of a map), which has been deconstructed1, leaving els
as the key and av
as the value of the current entry.
My gradle.build
is:
buildscript {
ext.kotlin_version = '1.2.21'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // for gradle build
}
}
apply plugin: 'kotlin'
repositories { jcenter() }
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
sourceSets.main {
kotlin.srcDirs += 'src/kotlin'
resources.srcDirs += 'src/resources'
}
jar {
baseName 'myApp'
manifest.attributes 'Main-Class': 'MainKt' // '[namespace].[arctifact/file]Kt'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
The generated jar
file was saved at build/libs/MyApp.jar
and i run it using command java -jar myApp.jar
solved Equivalent Kotlin code to my F# functional code [closed]