Peta pikir

training_kotlin

Pemrograman fungsional

Latihan diambil dari buku:
Pemrograman fungsional dalam Kotlin oleh tutorial
Ditulis oleh Massimo Carli
repo: https://github.com/kodecocodes/fpk-materials

Sintaksis

FirstProgramTest

konsep: tampilan layar, fungsi
FirstProgramTest:https://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/programming/FirstProgramTest.kt[sumber]+

ConcatFunctionTest

konsep: memori, variabel, nilai, objek, ekstensi fungsi
ExampleUnitTest: sumber+

BirthdayMessageTestOutput

konsep: himpunan, loop
Pengantar kotlin
BirthdayMessageTestOutput:https://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/programming/BirthdayMessageTestOutput.kt[sumber]+

Kursus kotlin

Tutorial koleksi di Java

Jantung antarmuka koleksi
Koleksi

dasar fungsional

pendekatan deklaratif X imperatif

package functional

import kotlin.test.Test
import kotlin.test.assertEquals

class DeclarativeTests {
    val input = listOf(
        "123", "abc", "1ds", "987", "abdf", "1d3", "de1", "88", "101"
    )

    fun imperativeSum(list: List<String>): Int {
        var sum = 0
        for (item in list) {
            try {
                sum += item.toInt()
            } catch (_: NumberFormatException) {
            }
        }
        return sum
    }

    @Test
    fun `test imperative approach`() {
        imperativeSum(input).run {
            println("Sum $this")
            assertEquals(1299, this)
        }
    }

    fun isValidNumber(s: String) = try {
        s.toInt()
        true
    } catch (_: NumberFormatException) {
        false
    }

    fun declarativeSum(list: List<String>) = list
        .filter(::isValidNumber)
        .map(String::toInt)
        .sum()

    @Test
    fun `test declarative approach`() {
        assertEquals(1299, declarativeSum(input).apply {
            println("Sum $this")
        })
    }
}

Latihan 1.1

Implementasikan fungsi sumInRange, yang menjumlahkan nilai-nilai di dalam
sebuah List<String> dalam rentang yang diberikan. tanda tangan adalah :

fun sumInRange(input: List<String>, range: IntRange): Int
@Test
fun `Exercise 1_1`() {
    assertEquals(4, sumInRange(
        listOf("1", "10", "a", "7", "ad2", "3"),
            1..5
        ).apply { println("sumInRange 1..5: $this") }
    )
}

Cobalah dan periksa jawaban Anda denganhttps://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/functional/DeclarativeTests.kt[solusi, windows="_blank].

fungsi orde tinggi

package functional

import java.io.ByteArrayOutputStream
import java.io.PrintStream
import java.lang.System.*
import java.lang.Thread.sleep
import kotlin.math.sign
import kotlin.test.Test
import kotlin.test.assertEquals

class BasicsHOFTests {
    val ONE_SECOND = 1000L

    @Test
    fun `high order function`() {
        //capture de la sortie standard
        val standardOut: PrintStream? = out
        val outputStreamCaptor = ByteArrayOutputStream()
        setOut(PrintStream(outputStreamCaptor))

        3.times { println("Hello") }
        assertEquals(
            buildString {
                repeat(3) { append("Hello\n") }
                deleteAt(length - 1)
            }, outputStreamCaptor
                .toString()
                .trim()
        )

        //libération de la sortie standard
        setOut(standardOut)
    }

    fun Int.times1(fn: () -> Unit) {
        for (i in 1..this) {
            fn()
        }
    }

    fun Int.times2(fn: () -> Unit) {
        for (i in 1..this) fn()
    }

    fun Int.times3(fn: () -> Unit) =
        (1..this).forEach { fn() }


    fun Int.times4(fn: () -> Unit) =
        repeat((1..this).count()) { fn() }

    fun Int.times(fn: () -> Unit) =
        (1..this).forEach { _ -> fn() }
}

Latihan 1.2

Menerapkan chrono, yang menerima fungsi dengan tipe`() →`
Unit pada masukan dan mengembalikan waktu yang dihabiskan untuk mengeksekusinya. Tanda tandanya:

fun chrono(fn : () -> Unité) : Long
@Test
fun `Exercise 1_2`() {
    val waitOneSec = { sleep(ONE_SECOND) }
    chrono(waitOneSec).apply {
        println("chrono: $this")
        assertEquals(1, sign)
    }
}

Coba itu dan periksa jawaban Anda denganhttps://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/functional/BasicsHOFTests.kt[solusi, windows="_blank].

komposisi

package functional

import kotlin.test.Test
import kotlin.test.assertEquals


fun double(x: Int): Int = 2 * x
fun square(x: Int): Int = x * x
fun squareAndDouble1(x: Int) = double(square(x))

infix fun <A, B, C> ((A) -> B).compose(g: (B) -> C)
        : (A) -> C = { a -> g(this(a)) }

class CompositionTests {
    @Test
    fun composition_impure() {
        assertEquals(200, double(square(10)))
        assertEquals(200, squareAndDouble1(10))
    }

    @Test
    fun composition_pure() {
        val squareAndDouble = ::square compose ::double
        assertEquals(200, squareAndDouble(10))
    }

}

Fungsi murni dan kemampuan diuji

package functional

import java.io.ByteArrayOutputStream
import java.io.PrintStream
import java.lang.System.out
import java.lang.System.setOut
import kotlin.test.Test
import kotlin.test.assertEquals


var count = 0

//impure car une variable global subit un effet de bord
fun impure(value: Int): Int {
    count++
    return value + count
}

//impure car utilisation de la sortie standard qui fait muter le system
fun addOneAndLog(x: Int): Int {
    val result = x + 1
    println("New Value is $result")
    return result
}

//pure
fun addOne(x: Int) = (x + 1).run {
    Pair(this, "New Value is $this")
}

class PureTests {
    @Test
    fun `impure fonction`() {
        assertEquals(3, impure(2))

        val standardOut = out
        val outputStreamCaptor = ByteArrayOutputStream()
        setOut(PrintStream(outputStreamCaptor))

        addOneAndLog(3)

        assertEquals(
            "New Value is 4",
            outputStreamCaptor
                .toString()
                .trim()
        )
        setOut(standardOut)
    }

    @Test
    fun `pure fonction`() {
        addOne(3).run {
            assertEquals(4, first)
            assertEquals("New Value is 4", second)
        }
    }
}

Penanganan pengecualian

package functional

import org.junit.jupiter.api.assertThrows
import kotlin.Result.Companion.failure
import kotlin.Result.Companion.success
import kotlin.test.Test
import kotlin.test.assertEquals

//NumberFormatException est un effet de bord qui rend la fonction impure
fun strToInt(str: String) = str.toInt()

//pure
fun strToIntOrNull(str: String) = try {
    str.toInt()
} catch (nfe: NumberFormatException) {
    null
}

//pure avec gestion de l'exception plus élégante
fun strToIntResult(str: String): Result<Int> =
    try {
        success(str.toInt())
    } catch (nfe: NumberFormatException) {
        failure(nfe)
    }

class ExceptionHandlingTests {
    @Test
    fun impure() {
        assertThrows<NumberFormatException> { strToInt("foo") }
        assertEquals(1, strToInt("1"))
    }

    @Test
    fun pure() {
        assertEquals(null, strToIntOrNull("foo"))
        assertEquals(1, strToIntOrNull("1"))
    }

    @Test
    fun `pure avec result`() {
        assertEquals(1, strToIntResult("1").getOrNull())
        assertEquals(
            "For input string: \"foo\"",
            strToIntResult("foo")
                .exceptionOrNull()
                ?.message
        )
    }
}

poin-poin kunci

  • Sementara pemrograman berorientasi objek berarti memprogram dengan objek,

pemrograman fungsional berarti memprogram dengan fungsi. Anda memecah masalah menjadi beberapa sub-masalah, yang Anda modelkan dengan fungsi-fungsi.

  • Fungsi orde tinggi menerima fungsi lain sebagai input atau mengembalikan fungsi lain

berfungsi sebagai nilai pengembalian. Teori kategori adalah teori komposisi, dan Anda menggunakannya untuk memahami bagaimana menyusun fungsi-fungsimu dalam sebuah program kerja Nilai output dari fungsi murni hanya tergantung pada parameter inputnya, dan ia tidak memiliki efek samping

  • Sebuah efek samping adalah sesuatu yang dilakukan oleh sebuah fungsi ke dunia luar. Ini

mungkin menjadi log di output standar atau modifikasi nilai variabel global Pemrograman fungsional berfungsi untuk fungsi murni, tetapi juga menyediakan alat untuk mengubah fungsi tidak murni menjadi fungsi murni. Anda dapat membuat fungsi tidak murni menjadi murni dengan memindahkan efek untuk membuatnya bagian dari nilai pengembalian

  • Pemrograman fungsional adalah tentang komposisi.

Penanganan kesalahan adalah contoh khas efek samping, dan Kotlin memberi Anda alat. untuk mengelola mereka secara fungsional.

Mendalam java8: ekspresi lambda dan antarmuka fungsional

Teori Kategori

Teori matematika kategori:

Dasar-dasar fungsi

Latihan 2.1

Bisakah Anda menulis contoh fungsi yang memetakan nilai yang berbeda
yang memiliki domain dengan nilai-nilai yang tidak berbeda dalam rentang, seperti f(b) dan f(c) dalam gambar di bawah ini?

Cobalah, lalu periksa proyek tantangan untuk solusi yang menunjukkan bagaimana kamu melakukannya.
Anda akan menemukan saran dan penjelasan dengan mengikuti tautan ke solusi.

Latihan 2.2

Bisakah kamu menulis fungsi invers dari dua kali ?
Apa domain dan jangkauan untuk fungsi invers?
Lihat proyek tantangan dan Lampiran B untuk solusi.

fun chrono(fn : () -> Unité) : Long
@Test
fun `Exercise 1_2`() {
    val waitOneSec = { sleep(ONE_SECOND) }
    chrono(waitOneSec).apply {
        println("chrono: $this")
        assertEquals(1, sign)
    }
}

Coba dan periksa jawaban Anda denganhttps://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/functional/BasicsHOFTests.kt[solution, windows="_blank].

Artikel terkait