마인드 맵

training_kotlin

함수형 프로그래밍

이 연습 문제는 책에서 발췌되었습니다:
튜토리얼로 배우는 Kotlin 함수형 프로그래밍
Massimo Carli가 작성함
저장소: https://github.com/kodecocodes/fpk-materials

구문

첫 프로그램 테스트

개념: 화면 표시, 기능
첫 프로그램 테스트:https://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/programming/FirstProgramTest.kt[source]+

연결 함수 테스트

개념: 메모리, 변수, 값, 객체, 함수 확장
ExampleUnitTest: 출처+

생일 메시지 테스트 출력

개념: 집합, 루프
Kotlin 소개
BirthdayMessageTestOutput:https://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/programming/BirthdayMessageTestOutput.kt[출처]+

코틀린 강의

자바 컬렉션에 대한 튜토리얼

컬렉션 인터페이스의 핵심
컬렉션

기본적인 기능

선언적 X 명령형 접근

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

연습 1.1

sumInRange 함수를 구현하라, 이 함수는 값들을 더한다
주어진 구간 내의 List<String>. 서명은:

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

해보세요, 그리고 라와 함께 답변을 확인하세요https://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/functional/DeclarativeTests.kt[해결책, 창="_blank].

고차 함수

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

문제 1.2

타입인 함수를 받아들이는 chrono를 구현하세요`() →`
입력으로 받고 실행에 걸린 시간을 반환합니다. 서명 :

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

해보고 당신의 답을 확인해 보세요와 함께https://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/functional/BasicsHOFTests.kt[솔루션, windows="_blank].

구성

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

}

순수 함수와 테스트 가능성

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

예외 처리

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

핵심 포인트

  • 객체 지향 프로그래밍은 객체로 프로그래밍하는 것을 의미한다,

함수형 프로그래밍은 함수를 사용해 프로그래밍하는 것을 의미합니다. 당신은 문제를 여러 하위 문제로 나누고, 그것을 모델링하여 함수들

  • 고차 함수는 다른 함수를 입력으로 받거나 다른 함수를 반환합니다.

반환 값처럼 동작합니다. 카테고리 이론은 구성의 이론이며, 당신은 이것을 이해하기 위해 사용합니다. 작업 프로그램에서 함수를 어떻게 구성하는지 순수 함수의 출력 값은 오직 그 입력 매개변수에만 의존하고, 그것 부작용이 없습니다.

  • 부작용은 함수가 외부 세계에 미치는 무언가입니다. 이

표준 출력에 로그가 될 수도 있고 전역 변수의 값이 수정될 수도 있습니다. 함수형 프로그래밍은 순수 함수에 대해 작동하지만, 또한 제공한다 불순한 함수를 순수한 함수로 변환하는 도구들 효과를 이동시켜 그것들을 순수하게 만들 수 있습니다 반환 값의 일부.

  • 함수형 프로그래밍은 구성의 문제입니다.

오류 관리는 부작용의 전형적인 사례이며, Kotlin은 도구를 제공합니다. 것들을 기능적으로 관리하기 위해

자바8 심화: 람다 표현식 및 함수형 인터페이스

범주론

수학적 범주 이론:

함수의 기초

연습 2.1

구분된 값을 매핑하는 함수의 예를 작성할 수 있나요?
도메인이 범위 내에서 중복된 값을 가지는 경우, 아래 그림과 같이 f(b)와 f(c)와 같은 ?

해보고, 어떻게 했는지 보려면 챌린지 프로젝트의 솔루션을 확인해 보세요.
링크를 따라가면 조언과 설명을 찾을 수 있습니다. 해결책.

연습 2.2

두 배 함수의 역함수를 작성할 수 있나요?
역함수의 정의역과 치역은 무엇인가요?
해결책을 보려면 챌린지 프로젝트와 부록 B를 확인하세요.

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

시도해 보세요 그리고 당신의 답을 확인해 보세요https://github.com/cheroliv/cheroliv.com/blob/master/codes/src/test/kotlin/functional/BasicsHOFTests.kt[해결책, windows="_blank].

관련 기사