[kotlin] 코틀린을 다루는 기술 — 4장 재귀, 공재귀, 메모화
2021. 6. 21. 14:42ㆍ모바일/Android_Kotlin
코틀린을 다루는 기술 — 4장 재귀, 공재귀, 메모화
concat
- concat을 사용하면 기존의 리스트에 새로운 리스트를 추가하여 새 리스트를 반환한다
- 끝에 NIL포인터를 새 리스트로 연결시킨다
나머지 설명
- LIst 클래스에는 2개의 비공개 하위 클래스가 있다. 한 가지는 빈 리스트를 표현하는 Nil이고, 다른 하나는 비어있지 않은 리스트를 표현하는 Cons이다.
- 자세한 설명은 주석에 달아놓았다.
fun main() {
// println(add(2))
// val squareOfTriple = compose(::square,::tripe)
// var lit :List<Char> = arrayListOf('d','d')
// print(toString(lit,"string"))
val a :MyList<Int> = MyList(1,2,3)
//위 코드는 List의 생성자를 호출하는게 아닌, companio object의 invoke 함수를 호출한다.
val b = a.concat(MyList.invoke(1,2,3,24,2))
println(a)
//[1, 2, 3, NIL]
println(b)
//[1, 2, 3, 1, 2, 3, 24, 2, NIL]
}
open class Pair<A,B>(val first:A,val second:B)
//class MyList<A>(private val head : A, val tail:MyList<A>):Pair<A,MyList<A>>(head,tail)
sealed class MyList<A> {
abstract fun isEmpty(): Boolean
abstract fun setHead(a: A): MyList<A>
fun cons(a: A): MyList<A> = Cons(a, this)
fun drop(n: Int): MyList<A> = drop(this, n)
fun dropWhile(p: (A) -> Boolean): MyList<A> = dropWhile(this, p)
fun concat(list: MyList<A>): MyList<A> = concat(this, list)
fun init(): MyList<A> = TODO("init")
fun reverse(): MyList<A> = TODO("reverse")
internal object Nil: MyList<Nothing>() {
override fun setHead(a: Nothing): MyList<Nothing> = throw IllegalStateException("setHead called on an empty list")
override fun isEmpty() = true
override fun toString(): String = "[NIL]"
}
internal class Cons<A>(val head: A, val tail: MyList<A>): MyList<A>() {
//A(머리) , MyList<A> 꼬리를 인자로 받는다.
//두 인자를 내부 가시성으로 선언해 List 클래스가 선언된 파일 안에서만 볼수 있게 한다.
//Nil과 Cons를 비공개 가시성으로 선언해 항상 동반 객체의 invoke함수를 통해서만 리스트를 만들게 강제한다.
override fun setHead(a: A): MyList<A> = tail.cons(a)
override fun isEmpty() = false
override fun toString(): String = "[${toString("", this)}NIL]"
private tailrec fun toString(acc: String, list: MyList<A>): String = when (list) {
Nil -> acc
is Cons -> toString("$acc${list.head}, ", list.tail)
}
}
companion object {
tailrec fun <A> drop(list: MyList<A>, n: Int): MyList<A> = when (list) {
Nil -> list
is Cons -> if (n <= 0) list else drop(list.tail, n - 1)
}
tailrec fun <A> dropWhile(list: MyList<A>, p: (A) -> Boolean): MyList<A> = when (list) {
Nil -> list
is Cons -> if (p(list.head)) dropWhile(list.tail, p) else list
}
fun <A> concat(list1: MyList<A>, list2: MyList<A>): MyList<A> = when (list1) {
Nil -> list2
is Cons -> concat(list1.tail, list2).cons(list1.head)
}
tailrec fun <A> reverse(acc: MyList<A>, list: MyList<A>): MyList<A> = when (list) {
Nil -> acc
is Cons -> reverse(acc.cons(list.head), list.tail)
}
operator fun <A> invoke(vararg az: A): MyList<A> =
az.foldRight(Nil as MyList<A>) { a: A, list: MyList<A> -> Cons(a, list) }
}
}
'모바일 > Android_Kotlin' 카테고리의 다른 글
[Kotlin] apply, with, let, also, run, 범위 지정, 수신 객체 지정 람다, 확장함수 (0) | 2021.06.21 |
---|---|
[kotlin] High-Order-Function (0) | 2021.06.18 |
[kotlin] inline , noinline, crossline function (0) | 2021.06.18 |
[kotlin] class, object, companion object (0) | 2021.06.17 |
[kotlin] 함수 리터럴 (with receiver) (0) | 2021.06.17 |