Scala의 Eta 확장

2529 단어 scalascala3

에타 확장



"Can you tell me about Eta Expansion?"



나는 얼었다. 맥박이 오르고 체온이 오르기 시작했으며 목이 말랐습니다. 메서드와 함수, Scala가 OO인 방식에 대해 중얼거렸습니다. 하지만 몰랐습니다, 죄송합니다! 그만 쳐다봐.

이것은 Scala 계약에 대한 인터뷰에서 상당히 무해한 질문에 대한 나의 반응이었습니다. 그 일은 결코 풀리지 않았습니다. 회사는 분명히 제안을 하고 싶었고, 아쉽게도 내부 정치가 개입했습니다. 그러나 나는 그 질문에 대한 일관된 대답의 부족이 나를 몰락하게 만들었다고 생각하지 않을 수 없습니다!

덧붙여서 이것은 면접 상황에서 내가 가지고 있는 특이한 반응이 아닙니다. 다행스럽게도 코딩은 교과서 프로세스 설명의 즉각적인 리콜과 문제 해결과 관련된 모든 것과는 관련이 없지만 30분 인터뷰에서 실제로 테스트할 좋은 방법은 없습니다. 여기 있습니다.

이 블로그는 그 질문에 대한 실제 답변을 작성하고 그렇게 함으로써 일반적으로 Scala와 FP에 대한 추가 통찰력을 얻으려는 시도입니다.

Eta 확장이란 무엇입니까?



FP의 핵심 원칙 중 하나는 기능이 일급 시민이라는 것입니다. 값으로 무언가를 할 수 있다면 함수로도 할 수 있습니다. List 클래스에서 메소드 맵의 정의를 고려하십시오.

final def map[B](f: (A) => B): List[B]

aList[A]의 map은 요소를 유형 A에서 유형 B로 매핑하고 aList[B]를 반환하는 함수를 인수로 사용함을 볼 수 있습니다.

그래서 우리는 숫자를 이렇게 문자열로 바꿀 수 있습니다.

List(1, 2, 3).map(n => n.toString)

지금까지 매우 기능적입니다. 우리의 익명 함수는 함수 A => B(또는 이 경우 Int => String)를 취하는 map의 시그니처를 충족합니다.

하지만 메서드를 전달하고 싶다면 어떻게 해야 할까요? 우리는 스칼라가 OO라는 것을 알고 있으므로 우리가 말할 때

def f(n: Int): String = ...

f는 함수가 아니라 작업 중인 클래스의 메서드입니다. 함수를 다음과 같이 정의합니다.

val f: (Int) => String = ...

그리고 (Scala 2.x에서) 우리는 리스트에 함수를 넣을 수 있지만(첫 번째 클래스, 기억하세요), 메서드는 넣을 수 없습니다.

val fFunction: (Int) => String = ...
def fMethod(n: Int): String = ...
List(fFunction) // ok
List(fMethod)   // not ok

(Scala 3에서는 그렇지 않습니다. Scala 3에서는 Eta Expansion을 개선하여 이를 허용하고 자동 확장 카레 기능 지원도 추가했습니다.)

하지만 잠시만 기다려 주세요. 제 Scala 컴파일러가 기쁘게 허용할 것입니다.

def f(n: Int): String = 
....
List(1, 2, 3).map(f)

그리고 이것이 Eta Expansion이 들어오는 곳입니다. 휴! 작동 방식을 건드리지 않고 갈 길이 멀다.

다음과 같은 함수를 정의할 때 주목할 가치가 있습니다.

val f: (Int) => String = ...

이것은 통사론적 설탕이며 실제로 후드 아래에 있는 것은 특성 FunctionN을 구현하는 객체입니다. 특히 이 경우에는

Function1[Int, String]

그리고 주어진 인수에 함수를 적용하는 관련 적용 메서드입니다.

Eta Expansion이 어느 정도 확장되었습니다. 특히 Scala 3에는 풀어야 할 것이 더 많으므로 나중에 다시 언급할 수 있습니다.

좋은 웹페이지 즐겨찾기