Sơ đồ tư duy

training_kotlin

Lập trình hàm

Các bài tập được trích từ cuốn sách:
Lập trình hàm trong kotlin qua các bài hướng dẫn
Được viết bởi Massimo Carli
repo: https://github.com/kodecocodes/fpk-materials

Cú pháp

FirstProgramTest

khái niệm: hiển thị màn hình, hàm
FirstProgramTest:https://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/programming/FirstProgramTest.kt[nguồn]+

ConcatFunctionTest

khái niệm: bộ nhớ, biến, giá trị, đối tượng, mở rộng hàm
ExampleUnitTest:https://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/programming/ConcatFunctionTest.kt[nguồn]+

KếtQuảKiểmTraTinNhắnSinhNhật

khái niệm: tập hợp, vòng lặp
Giới thiệu về kotlin
KếtQuảKiểmTraTinNhắnSinhNhật:https://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/programming/BirthdayMessageTestOutput.kt[nguồn]+

Khóa học Kotlin

Hướng dẫn về các collection trong java

Trọng tâm của các giao diện thu thập
hình ảnh:../../img/0036_training_kotlin_post/colls-coreInterfaces.gif[Collections]

Các kiến thức cơ bản về functional

Cách tiếp cận Declarative X imperative

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")
        })
    }
}

Bài tập 1.1

Triển khai hàm sumInRange, hàm này cộng các giá trị trong
một List<String> trong một khoảng cho trước. Chữ ký là:

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") }
    )
}

Hãy thử nó và kiểm tra câu trả lời của bạn với lahttps://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/functional/DeclarativeTests.kt[giải pháp, windows="_blank]Vui lòng cung cấp nội dung cần dịch.

Hàm bậc cao

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() }
}

Bài tập 1.2

Triển khai chrono, chấp nhận một hàm có kiểu`() →`
Đơn vị đầu vào và trả về thời gian thực thi. Chữ ký là:

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

Hãy thử nó và kiểm tra câu trả lời của bạn vớihttps://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/functional/BasicsHOFTests.kt[giải pháp, windows="_blank].

Bố cục

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))
    }

}

Hàm thuần khiết và khả năng kiểm thử

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)
        }
    }
}

Xử lý ngoại lệ

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
        )
    }
}

Các điểm chính

  • Trong khi lập trình hướng đối tượng có nghĩa là lập trình với các đối tượng,

lập trình hàm có nghĩa là lập trình với các hàm. Bạn chia nhỏ một vấn đề thành nhiều vấn đề con, sau đó mô hình hóa chúng bằng các hàm.

  • Các hàm bậc cao chấp nhận các hàm khác làm đầu vào hoặc trả về các hàm khác

hoạt động như các giá trị trả về. Lý thuyết phạm trù là lý thuyết về sự hợp thành, và bạn sử dụng nó để hiểu cách xây dựng các hàm của bạn trong một chương trình làm việc. Giá trị đầu ra của một hàm thuần khiết chỉ phụ thuộc vào các tham số đầu vào của nó, và nó không có tác dụng phụ.

  • Một tác dụng phụ là điều mà một hàm thực hiện đối với thế giới bên ngoài. Điều này

có thể là một bản ghi trong đầu ra tiêu chuẩn hoặc việc thay đổi giá trị của một biến toàn cục. Lập trình hàm hoạt động cho các hàm thuần khiết, nhưng nó cũng cung cấp các các công cụ để chuyển đổi các hàm không thuần khiết thành các hàm thuần khiết. Bạn có thể biến một hàm không thuần khiết thành thuần khiết bằng cách di chuyển các tác vụ phụ để khiến chúng một phần của giá trị trả về.

  • Lập trình hàm là vấn đề về sự kết hợp.

Xử lý lỗi là một trường hợp điển hình của hiệu ứng lề (side effects), và Kotlin cung cấp cho bạn các công cụ để quản lý chúng một cách chức năng.

Tìm hiểu sâu về java8: biểu thức lambdas và interface chức năng

Lý thuyết phạm trù

Lý thuyết phạm trù toán học:

Những kiến thức cơ bản về hàm số

Bài tập 2.1

Bạn có thể viết một ví dụ về hàm ánh xạ các giá trị riêng biệt
mà miền xác định có các giá trị không phân biệt trong vùng, chẳng hạn như f(b) và f(c) trong hình dưới đây?

Hãy thử nó, sau đó kiểm tra dự án thử thách để xem giải pháp và cách bạn đã thực hiện.
Bạn sẽ tìm thấy các lời khuyên và giải thích bằng cách theo đường dẫn đến giải pháp.

Bài tập 2.2

Bạn có thể viết hàm ngược của twice không?
Tập xác định và tập giá trị của hàm ngược là gì?
Hãy xem dự án thử thách và Phụ lục B để biết lời giải.

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

Hãy thử nó và kiểm tra câu trả lời của bạn với lahttps://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/functional/BasicsHOFTests.kt[giải pháp, windows="_blank]Vui lòng cung cấp văn bản cần dịch.

Bài viết liên quan