교육 - Kotlin
게시: 12 May 2022
마인드 맵

함수형 프로그래밍
이 연습 문제는 책에서 발췌되었습니다:
튜토리얼로 배우는 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].
관련 기사
31 May 2026
14 May 2026
