복붙노트

[SCALA] 스칼라 오버 방식과 방법 및 기능 사이 에타 팽창

SCALA

스칼라 오버 방식과 방법 및 기능 사이 에타 팽창

나는 ETA-확장 (§6.26.5는) 오버로드 메소드하지 작업을 수행 이유를 이해하고 싶습니다. 예를 들어, 나는 두 가지 방법으로 다음과 같은 경우 :

def d1(a: Int, b: Int) {}
def r[A, B](delegate: (A, B) ⇒ Unit) {}

나는이 작업을 수행 할 수 있습니다

r(d1)

그러나, 경우 더 이상 작업을위한 R 오버로드 :

def r[A, B](delegate: (A, B) ⇒ Unit) {}
def r[A, B, C](delegate: (A, B, C) ⇒ Unit) {}

r(d1) // no longer compiles

내가 명시 적으로 부분적으로 적용된 기능으로 방법을 변환해야합니다 :

r(d1 _)

명시 적 변환을 다음 달성 할 수있는 방법이 있습니까?

def r[A, B](delegate: (A, B) ⇒ Unit) {}
def r[A, B, C](delegate: (A, B, C) ⇒ Unit) {}

def d1(a: Int, b: Int) {}
def d2(a: Int, b: Int, c: Int) {}

r(d1) // only compiles with r(d1 _)
r(d2) // only compiles with r(d2 _)

이 다소 비슷한 질문이지만, 완전히 설명되지 않습니다.

해결법

  1. ==============================

    1.암시는 올바른 용어이며, 섹션은 사양에서 6.26.2이며,이 중복 질문을해야합니다 (또는 하나의 생각 때문에, 이것은 안정적인 동작입니다).

    암시는 올바른 용어이며, 섹션은 사양에서 6.26.2이며,이 중복 질문을해야합니다 (또는 하나의 생각 때문에, 이것은 안정적인 동작입니다).

    링크 된 질문은 예상되는 유형이 기능해야한다는 응답합니다.

    나는 사지에 나가서 오버로드 된 경우에는 예상되는 유형 (6.26.3, 악명)이 없기 때문에 적용이 훼손되고 말 것입니다. 오버로드하지 않을 때 상기 파라미터의 유형이 예상 유형을 결정하기 때문에, 6.26.2은 (ETA 확장)을 적용한다. 오버로드 된 경우, 인수가 구체적으로 어떤 예상되는 형태로 입력되며, 따라서 6.26.2이 적용되지 않습니다; D의 그러므로 어느 쪽도 오버하지 변형이 적용되는 것으로 간주됩니다.

    여기에 "암시 적 변환"는 인수하지 않고하는 방법을 이름을 지정할 때 R (D1)에서와 같이 사용할 수 (소위)입니다. ETA 확장에 단락이 여기에 적용됩니다.

    더 후 녹색 체크 설명 ...

    다음의 예는 오버로드의 존재 ETA-확장에 응용 프로그램을 선호 보여줍니다. ETA-확장이 적용되지 않는 경우, "빈 응용 프로그램은"6.26.2에 시도 할 최종 암시입니다. (그것의 얼굴에 혼란 악에 충분한되는) 과부하 때 즉, _는 균일 한 액세스 원리에 의해 F ()와 같은 F를 취할 자연이지만, F로 f를 취할 자연스러운 또는 이상한 당신 않는 한 '확신 함수 유형이 예상되는 재.

    scala> object Bar {
         | def r(f: () => Int) = 1
         | def r(i: Int) = 2
         | }
    defined module Bar
    
    scala> def f() = 4
    f: ()Int
    
    scala> Bar.r(f)
    res4: Int = 2
    
    scala> Bar.r(f _)
    res5: Int = 1
    

    해상도 과부하 후보는 "모양"에 의해 사전 상영된다. 모양 시험은 인수가 예상 타입없이 입력되기 때문에 ETA-확장이 사용되지 않습니다 그 직관을 캡슐화합니다. 이 때 ETA-확장도 사용되지 않음을이 예제 쇼 "유형 검사로 표현하는 유일한 방법입니다."

    scala> object Bar {
         | def bar(f: () => Int) = 1
         | def bar(is: Array[Int]) = 2
         | }
    defined object Bar
    
    scala> def m() = 7
    m: ()Int
    
    scala> m _
    res0: () => Int = <function0>
    
    scala> Bar.bar(m)
    <console>:10: error: overloaded method value bar with alternatives:
      (is: Array[Int])Int <and>
      (f: () => Int)Int
     cannot be applied to (Int)
                  Bar.bar(m)
                      ^
    

    여기까지를 읽는 사람은이 두 가지 변환과 관련된 문제에 대한 호기심이 될 것입니다.

  2. from https://stackoverflow.com/questions/17324247/eta-expansion-between-methods-and-functions-with-overloaded-methods-in-scala by cc-by-sa and MIT license