// 01. use 파라미터 + effects 절이 한 시그니처에 동시에 붙는 모양 // // 어순: fn 이름(파라미터) effects {...} -> 반환타입 // 검증 대상: capability를 받는 평범한 함수가 사람이 읽을 만한가. import "cool.dev/std/list" as List pub fn refund_order( use pay: PaymentGateway, id: OrderId, ) effects {PaymentGateway.refund} -> Result { pay.refund(id) } // capability 둘, effect 둘. pub fn refund_and_log( use pay: PaymentGateway, use log: Logger, id: OrderId, ) effects {PaymentGateway.refund, Logger.write} -> Result { let receipt = pay.refund(id)? log.write("refunded: ", id) Ok(receipt) } // capability 셋 이상은 struct로 접는다 (표준 관용구). // Deps는 affine 필드를 가지므로 전이적으로 affine이고, use로 빌려 쓴다. pub struct Deps { pay: PaymentGateway, log: Logger, db: Database, } pub fn checkout( use deps: Deps, order: Order, ) effects {PaymentGateway.charge, Database.write, Logger.write} -> Result { let receipt = deps.pay.charge(order.id, order.amount)? deps.db.write(receipt)? deps.log.write("checkout: ", order.id) Ok(receipt) } // use 값을 다른 use 파라미터로 넘기는 것은 허용된다 (복제가 아니다). pub fn refund_all( use pay: PaymentGateway, ids: List, ) effects {PaymentGateway.refund} -> Result { List.each(ids, fn(id) { refund_order(pay, id)? Ok(unit) }) }