// 06. callable affinity — fn과 affine fn의 구분
//
// affinity(타입 속성)와 use/own(파라미터 위치 속성)은 직교한다.
// copyable 환경만 capture → fn. 복사해서 여러 번 써도 된다.
pub fn make_formatter(prefix: String) -> fn(String) -> String {
fn(s) { String.concat(prefix, s) }
}
// affine 값을 소유 → affine fn. 자신도 move 규칙을 따른다.
pub fn deferred_close(f: File) -> affine fn() effects {File.close} {
fn() { File.close(f) }
}
// 파라미터 위치이므로 use가 기본이지만, affine fn은 소유해야 호출 후 소비된다.
pub fn run_once(action: own affine fn() effects {File.close}) effects {File.close} {
action()
}
pub fn example(f: File) effects {File.close} {
let close = deferred_close(f)
run_once(close)
// run_once(close) // ERROR가 되어야 함: close는 affine, 이미 move됨
}
// use 클로저 — 표기가 없는 쪽이 흔한 쪽이다.
pub fn with_retry(
times: Int,
body: fn() effects e -> Result,
) effects e -> Result
pub fn refund_with_retry(
use pay: PaymentGateway,
id: OrderId,
) effects {PaymentGateway.refund} -> Result {
with_retry(3, fn() { pay.refund(id) })
}