이름에 의한 컨텍스트 파라미터
이름에 의한 컨텍스트 파라미터 (By-Name Context Parameters)
컨텍스트 파라미터는 발산하는(diverging) 추론된 확장을 피하기 위해 이름에 의한 파라미터(by-name parameter)로 선언할 수 있어요. 예를 들면 이런 코드죠.
trait Codec[T]:
def write(x: T): Unit
given intCodec: Codec[Int] = ???
given optionCodec: [T] => (ev: => Codec[T]) => Codec[Option[T]]:
def write(xo: Option[T]) = xo match
case Some(x) => ev.write(x)
case None =>
val s = summon[Codec[Option[Int]]]
s.write(Some(33))
s.write(None)
일반적인 이름에 의한 파라미터의 경우와 마찬가지로, 컨텍스트 파라미터 ev의 인자는 필요할 때 평가돼요. 위 예시에서 옵션 값 x가 None이면 ev는 전혀 평가되지 않아요.
컨텍스트 파라미터를 위해 합성된 인자는, 그렇지 않으면 발산하는 확장을 막는 데 필요하다면 지역 val로 뒷받침돼요.
타입 => T의 이름에 의한 컨텍스트 파라미터에 대한 인자를 합성하는 정확한 단계는 다음과 같아요.
- 타입
T의 새 given을 만듭니다.
given lv: T = ???
여기서 lv는 임의의 새로운(fresh) 이름이에요. 이 given은 인자 추론의 후보로 즉시 사용할 수 없어요. (즉시 사용 가능하게 만들면 합성된 계산에서 루프가 생길 수 있거든요.) 하지만 이름에 의한 컨텍스트 파라미터의 인자를 다시 찾는 모든 중첩된 컨텍스트에서는 사용할 수 있게 돼요.
- 그 검색이 표현식
E로 성공하고,E가lv에 대한 참조를 포함한다면,E를 다음처럼 바꿉니다.
{ given lv: T = E; lv }
- 그렇지 않으면
E를 그대로 돌려줍니다.
위 예시에서 s의 정의는 다음과 같이 확장돼요.
val s = summon[Test.Codec[Option[Int]]](
using optionCodec[Int](using intCodec)
)
합성된 인자가 재귀적이지 않기 때문에 지역 given 인스턴스는 생성되지 않았어요.
더 알아보기 (Learn more)
자세한 내용은 Issue #1998과 관련 Scala SIP을 참고하세요.