E021: 올바른 정의를 찾지 못함

E021: 올바른 정의를 찾지 못함 (Proper Definition Not Found)

이 에러는 Scaladoc 주석의 @usecase 애너테이션에 올바른 def 정의가 없을 때 발생해요.

출처: Scala 3 Reference

본문

Usecase는 def에만 지원돼요. 이 기능이 생긴 이유는 Scala의 발전된 타입 시스템 덕분에 때때로 겁먹게 생긴 시그니처가 나오는 경우가 있기 때문이에요. 하지만 이런 메서드의 사용은 겁먹을 필요가 없죠.

예를 들어 map 함수:

List(1, 2, 3).map(2 * _) // res: List(2, 4, 6)

는 이해하고 사용하기 쉽지만, 시그니처가 꽤 부피가 커요:

def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That

@usecase 애너테이션은 단순화된 시그니처를 문서화할 수 있게 해 줍니다:

/** Map from List[A] => List[B]
 *
 * @usecase def map[B](f: A => B): List[B]
 */
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That

Example

//> using options -Xcook-comments

class Example:
  /**
   * @usecase val x: Int
   */
  def complexMethod[A, B](f: A => B)(implicit ev: Ordering[A]): B = ???

Error

-- [E021] Doc Comment Error: example.scala:5:14 --------------------------------
5 |   * @usecase val x: Int
  |              ^
  |              Proper definition was not found in @usecase
  |
6 |   */
7 |  def complexMethod[A, B](f: A => B)(implicit ev: Ordering[A]): B = ???
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  | Usecases are only supported for defs. They exist because with Scala's
  | advanced type-system, we sometimes end up with seemingly scary signatures.
  | The usage of these methods, however, needs not be - for instance the map
  | function
  |
  | List(1, 2, 3).map(2 * _) // res: List(2, 4, 6)
  |
  | is easy to understand and use - but has a rather bulky signature:
  |
  | def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That
  |
  | to mitigate this and ease the usage of such functions we have the @usecase
  | annotation for docstrings. Which can be used like this:
  |
  | /** Map from List[A] => List[B]
  |   *
  |   * @usecase def map[B](f: A => B): List[B]
  |   */
  | def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That
  |
  |
  | When creating the docs, the signature of the method is substituted by the
  | usecase and the compiler makes sure that it is valid. Because of this, you're
  | only allowed to use defs when defining usecases.
   -----------------------------------------------------------------------------

Solution

//> using options -Xcook-comments

class Example:
  /**
   * Transforms elements.
   * @usecase def transform(f: Int => Int): List[Int]
   */
  def transform[A, B](f: A => B)(implicit ev: Ordering[A]): List[B] = ???

더 알아보기

  • @usecase 애너테이션은 Scaladoc에서만 사용돼요. 자세한 내용은 "Scala 3 Scaladoc" 문서를 참고하세요.