fun <T> List<T>.customAppend(inpList: List<T>): List<T>{
    val newList = mutableListOf<T>()

    newList.addAll(this)

    newList.addAll(inpList)

    return newList
}

fun <T> List<List<T>>.customConcat(): List<T>{
    val newList = mutableListOf<T>()

    this.forEach { newList.addAll(it) }

    return newList
}

fun <T> List<T>.customFilter(inpFunc: (T) -> Boolean): List<T>{
    val newList = mutableListOf<T>()

    for (i in this){
        if (inpFunc(i)){
            newList.add(i)
        }
    }

    return newList
}

fun <T, R> List<T>.customMap(inpFunc: (T) -> R): List<R>{
    val newList = mutableListOf<R>()

    for (i in this){
        newList.add(inpFunc(i))
    }

    return newList
}

val <T> List<T>.customSize: Int
    get() {
        var size = 0
        for (i in this){
            size++
        }
        return size
    }


fun <T, R> List<T>.customFoldLeft(acc: R, inpFunc: (R, T) -> R): R {
    if (this.isEmpty()){
        return acc
    }

    return this.drop(1).customFoldLeft(inpFunc(acc, this.first()), inpFunc)
}

fun <T, R> List<T>.customFoldRight(acc: R, inpFunc: (T, R) -> R): R{
    if (this.isEmpty()){
        return acc
    }

    return inpFunc(first(), this.drop(1).customFoldRight(acc, inpFunc))
}

fun <T> List<T>.customReverse(): List<T>{
    val newList = mutableListOf<T>()

    for (i in this){
        newList.add(0, i)
    }

    return newList
}