Created
April 23, 2025 14:29
-
-
Save hikaMaeng/1b073b08c327ff72d9402e307218df24 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
data class Holder<T>(private val value:T){ | |
companion object{ | |
fun <T, R> lift(block:(T)->R):(Holder<T>)->Holder<R> = {it.map(block)} | |
} | |
fun <R> map(block:(T)->R):Holder<R> = Holder(block(value)) | |
fun combine(other:Holder<T>, block:(T, T)->T):Holder<T> = map{ block(it, other.value) } | |
} | |
/* | |
map은 XXX만 주면 Holder생성함 | |
combine이 map의 비위만 맞춰주면 생성자 코드를 중복으로 쓰지 않겠지? | |
펑터는 map을 갖고 있다 | |
모나드는 flatmap갖고 있다 | |
어플리커티브는 map2갖고 있다 | |
폴더블 은 fold를 갖고 있다 | |
반군 결합법칙 요구 | |
실제 계산 전에 계산경로를 선언한다 ->DSL로 가는 길 | |
종결함수 | |
지연계산 | |
결합법칙 | |
합성 -> 최적화 | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.example.b | |
sealed interface Outcome<out ERROR, out VALUE>{ | |
fun <VALUE2> mapValue(block:(VALUE)->VALUE2):Outcome<ERROR, VALUE2> = when(this){ | |
is Success -> Success(block(value)) | |
is Failure -> this | |
} | |
fun <ERROR2> mapError(block:(ERROR)->ERROR2):Outcome<ERROR2, VALUE> = when(this){ | |
is Success -> this | |
is Failure -> Failure(block(error)) | |
} | |
} | |
data class Success<T>(val value:T):Outcome<Nothing, T> | |
data class Failure<E>(val error:E):Outcome<E, Nothing> | |
/* | |
val a:Outcome<Any, Any> = Outcome<Int, Int> | |
val a:Outcome<String, Int> = Success(3):Outcome<Nothing, Int> | |
모든 클래스의 부모 : object, any 어떤 타입이 와도 대체가능성 top upper bound | |
val a:Any = 어떤타입이 와도 성립 | |
모든 클래스의 자식 : nothing - 원래 타입이 뭐라도 nothing에게는 부모다 | |
val a:Int = Nothing 개념상 모든 타입의 자식이라니 코드가 성립하는건 알겠다 | |
이 밑으로는 실행하지 않겠어 = Nothing타입이 나오면 무조건 throw가 일어난다 런타임에서는 | |
컴파일타임에는 문제없이 컴파일 됨 | |
fun a():Int{throw ThrowException()} | |
val a:String = Nothing | |
*/ | |
//inline fun <ERROR, VALUE> Outcome<ERROR, VALUE>.onSuccess(block:(VALUE)->Nothing):ERROR = when(this){ | |
// is Success -> block(value) | |
// is Failure -> error | |
//} | |
//inline fun <ERROR, VALUE> Outcome<ERROR, VALUE>.onFailure(block:(ERROR)->Nothing):VALUE = when(this){ | |
// is Success -> value | |
// is Failure -> block(error) | |
//} | |
fun q7_2(){ | |
val a:Outcome<Int, Int> = Success(3) | |
val piped = a.mapValue { it + 1 }.mapError { "aaa" }.mapValue { it.toDouble() } //연산계획 pipeline - 결합법칙과 합성을 요구 | |
piped.onFailure { //터미널 연산 | |
println("error: $it") | |
}?.let{ | |
println("value: $it") | |
} | |
piped.onSuccess { | |
println("value: $it") | |
}?.let{ | |
println("error: $it") | |
} | |
val result = piped.recover { | |
//니가 어떤 io에러나 통신에러를 뱉어도 난 무조건 이상없이 이후 논리가 전개되는 값을 줄수 있어 | |
0.0 | |
} | |
// result로 뭘 해도 문제없음 | |
//여기서부터는 실행되지 않음 block이 호출되면 q7_2를 탈출함 | |
} | |
inline fun <ERROR, VALUE> Outcome<ERROR, VALUE>.onSuccess(block:(VALUE)->Unit):ERROR? = when(this){ | |
is Success -> { | |
block(value) | |
null | |
} | |
is Failure -> error | |
} | |
inline fun <ERROR, VALUE> Outcome<ERROR, VALUE>.onFailure(block:(ERROR)->Unit):VALUE? = when(this){ | |
is Success -> value | |
is Failure -> { | |
block(error) | |
null | |
} | |
} | |
inline fun <ERROR, VALUE> Outcome<ERROR, VALUE>.recover(block:(ERROR)->VALUE):VALUE = when(this){ | |
is Success -> value | |
is Failure -> block(error) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sealed class Outcome2<out ERROR, out VALUE>(val value:Any){ | |
companion object{ | |
fun <T:Any> runTry(block:()->T):Outcome2<Throwable, T> = try{ | |
Success(block()) | |
}catch (e:Throwable){ | |
Failure(e) | |
} | |
} | |
class Success<T:Any>(value:T):Outcome2<Nothing, T>(value as Any) | |
class Failure<E:Throwable>(error:E):Outcome2<E, Nothing>(error as Any) | |
fun <VALUE2:Any> map(block:(VALUE)->VALUE2):Outcome2<ERROR, VALUE2> = when(this){ | |
is Success -> Success(block(value as VALUE)) | |
is Failure -> this | |
} | |
fun <ERROR2:Throwable> mapError(block:(ERROR)->ERROR2):Outcome2<ERROR2, VALUE> = when(this){ | |
is Success -> this | |
is Failure -> Failure(block(value as ERROR)) | |
} | |
inline fun onSuccess(block:(VALUE)->Unit):ERROR? = when(this){ | |
is Success-> { | |
block(value as VALUE) | |
null | |
} | |
is Failure-> value as ERROR | |
} | |
inline fun onFailure(block:(ERROR)->Unit):VALUE? = when(this){ | |
is Success-> value as VALUE | |
is Failure-> { | |
block(value as ERROR) | |
null | |
} | |
} | |
} | |
inline fun <ERROR, VALUE> Outcome2<ERROR, VALUE>.recover(block:(ERROR)->VALUE):VALUE = when(this){ | |
is Outcome2.Success-> value as VALUE | |
is Outcome2.Failure-> block(value as ERROR) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.example | |
fun Long.isOdd():Boolean = this % 2L == 1L | |
fun longSeq(start:Long, end:Long) = sequence { | |
var i = start | |
while (i <= end) { | |
yield(i) | |
i += 1L | |
} | |
} | |
/* | |
연산과 메모리를 교환할 수 있다 | |
중학교 2학년 수학 교과서 부록편에는 sin표 (메모리) | |
내가 sin을 계산(연산 = 함수 = 함수형프로그래밍이란 메모리(상태)를 연산으로 표현하는 것 | |
지연연산 그때까지 계산하지 않겠어)으로 얻을 수도 있지만 sin표를 보고도 같은 값을 얻을 수 있다. = 결과는 동일 | |
*/ | |
fun LongRange.toLongSeq() = longSeq(this.first, this.last) | |
private tailrec fun <T> clone(list:List<T>, cursor:Int, acc:List<T>):List<T> | |
= if(cursor == list.size) acc else clone(list, cursor + 1, acc + list[cursor]) | |
fun <T> List<T>.dropFirst():List<T> = if(isEmpty()) this else clone(this, 1, emptyList()) | |
fun <T> List<T>.head():Pair<T?, List<T>> = firstOrNull() to dropFirst() | |
private tailrec fun <T> printLoop(list:List<T>){ | |
val (head, tail) = list.head() | |
if(head == null) return | |
else { | |
println(head) | |
printLoop(tail) | |
} | |
} | |
fun <T> List<T>.printAll() = printLoop(this) | |
fun q8_1(){ | |
val a = (1L..10L).toLongSeq().filter{ it.isOdd() }.map{ it * 2L } | |
val b = a.sum() | |
listOf(1,2,3,4,5).printAll() | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment