이펙트 핸들러(Effect Handlers, Algebraic Effects)는 부수 효과를 대수적으로 표현하고 처리하는 최신 프로그래밍 언어 기법이다. 모나드의 합성 문제를 해결하며 예외 처리, 협력적 멀티태스킹, 비결정성 등을 우아하게 다룬다.
핵심 개념
이펙트 = 연산(Operations)의 집합 + 핸들러
연산: perform (raise, read, write 등) → 효과 발동
핸들러: 발동된 효과를 해석 → 제어 흐름 결정
계속(Continuation): 효과 발동 이후의 나머지 계산
Koka 언어 예시
koka
// 이펙트 선언
effect state<s>
fun get() : s
fun put(x : s) : ()
// 이펙트를 사용하는 함수
fun increment() : state<int> ()
put(get() + 1)
// 핸들러로 이펙트 해석
fun run-state(init : s, action : () -> <state<s>|e> a) : e (a, s)
var st := init
with handler
fun get() resume(st) // 계속에 현재 상태 전달
fun put(x) st := x; resume(())
action()
ocaml
(* 이펙트 선언 *)
effect Read : int
effect Write : int -> unit
(* 이펙트 사용 *)
let program () =
let x = perform Read in
perform (Write (x + 1))
(* 핸들러 *)
let run_state init program =
let state = ref init in
match_with program () {
retc = (fun x -> (x, !state));
exnc = raise;
effc = fun (type a) (eff : a Effect.t) ->
match eff with
| Read -> Some (fun (k : (a, _) continuation) ->
continue k !state)
| Write v -> Some (fun k ->
state := v; continue k ())
| _ -> None
}
이펙트 vs 모나드 비교
| 비교 | 모나드 | 이펙트 핸들러 |
|---|
| 합성 | 모나드 변환자(복잡) | 자동 합성 |
| 유연성 | 고정된 해석 | 핸들러 교체 가능 |
| 제어 흐름 | 순방향만 | 다중 재개 가능 |
| 성능 | 일반적으로 빠름 | 계속 캡처 오버헤드 |
| 언어 지원 | Haskell, Scala | OCaml 5, Koka, Eff |
관련 개념