"리프팅 표현"이란 무엇입니까?


12

이 용어를 여기에서 실행하십시오.

http://www.codemesh.io/codemesh2014/viktor-klang

"우리는 Flow API (리프트 된 표현)와 리프팅 된 표현을 실행 표현 (Flow Materialization)으로 변환하는 플러그 가능한 방법을 보여줄 것입니다."

인터넷 검색은별로 도움이되지 않았습니다.


권장 독서 : $ {blog} 토론
gnat

11
@ gnat 그는 그 용어를 발명하지 않은 것처럼 보이며, 의견처럼 보이지 않으며 토론을 유발하지 않을 것이며 내 직감은 너무 넓지 않을 것입니다 (수학처럼 느껴지지만).
Den

2
나는 C #의 맥락에서 "lifted"의 의미에 대해 논의한다 : blogs.msdn.com/b/ericlippert/archive/2007/06/27/…- 아마도 스칼라 개발자 들이이 용어를 비슷한 용어로 사용하고있을 것입니다 일반적인 패션.
Eric Lippert

답변:


22

Flow API에 익숙하지 않습니다.

"리프팅"이라는 용어는 범주 이론에서 비롯됩니다. Haskell 또는 Scala와 같은 프로그래밍 언어에서 lift함수는 함수를 취하고 A => B어떤 식 으로든 마술을 수행하여 해제 된 함수 F[A] => F[B]를 functor 또는 monad에 적용 할 수 있습니다 F[A].

스칼라 Seq컨테이너 를 사용하는 구체적인 예 : function def double(x: Int): Int = 2 * x과 sequence 가 있다고 가정하십시오 val xs = Seq(1, 2, 3). double(xs)호환되지 않는 유형으로 인해 우리는 할 수 없습니다 . 우리가를 얻는다면 val doubleSeq = liftToSeq(double), 우리는 할 수있는 doubleSeq(xs)평가하는 Seq(2, 4, 6). 여기에서 liftToSeq구현할 수 있습니다

def liftToSeq[A, B](f: A => B): (Seq[A] => Seq[B]) =
  (seq: Seq[A]) => seq.map(f)

Seq(…)생성자는 값을 리프트 리프팅 동작으로 볼 수있다 1, 2, 3Seq따라서 우리가 이러한 값에 대한 목록 추상화를 사용할 수 있도록 인스턴스입니다.

Monads는 수밀하지만 구성 가능한 인터페이스를 제공하여 어떤 유형의 내부 작업을 캡슐화 할 수 있습니다. 해제 된 표현을 사용하면 계산에 대한 추론을 쉽게 할 수 있습니다. 이러한 추상화를 사용한다는 것은 추상화 된 특정 정보에 대한 지식을 잃는다는 것을 의미하지만, 적절한 실행 표현을 찾는 데있어 효율적인 구현을 제공하는 데 필요합니다.


4
그것은 수학적인 "리프팅"에 대한 좋은 설명입니다. 또한 위키피디아에서 리프팅에 대한보다 공식적인 설명을 참조해야합니다 .
Scott Whitlock

3
"리프팅"의보다 명확한 예는 널 입력 가능 (또는 "선택적"또는 "아마도") 유형으로 리프팅하는 것입니다. 예를 들어 +다음과 같이 정의 된 연산자가 있다고 가정하십시오 int + int --> int. 해제 가능 널 (null-to-nullable) 연산자 int? + int? --> int?의 의미는 "피연산자 중 하나가 널 (null)이면 응답이 널 (null)이면 그렇지 않으면 값에 대해 리프트되지 않은 연산자를 사용하십시오"라는 의미를 갖습니다.
Eric Lippert

@ScottWhitlock 당신도 들어 올리십니까?
helrich

1
@Frank 대답을 쓰기 전에 Wikipedia 기사를 읽었으며 이해하지 못했습니다. 대신에, 나는 발견 하스켈 위키리프팅 더 액세스 할 수 있습니다. 우리는 실제로 네 가지 유형이 없습니다. 우리는 4 가지 구체적인 유형을 가지고 있지만 3 가지 유형 변수 , 2 가지 유형 및 , 유형 생성자 인 functor 만 있습니다. ABF
amon

1
나는이 모든 것에 너무 깊지 F는 않지만 유형 생성자 인 경우 F[A]구성된 유형 중 하나입니다. 그렇다면이 네 가지 유형에 대해 말하는 것이 왜 잘못 되었습니까? (물론 두 유형과 하나의 유형 생성자가 동일하게 괜찮을 것입니다)
Frank

6

물론 리프트 라는 용어 는 상황에 따라 다른 의미를 가질 수 있습니다.

일반 프로그래밍 에서는 다음 상위 레벨로 추상화하는 프로세스를 설명합니다. 예를 들어, 코드 유형은 int, 코드 유형은 두 가지가 있습니다 float. 이 코드를 리프팅하는 것은 제네릭 형식과 방법을하는 주형과 같은 의미 T모두를 위해 작동 int하고 float.

나는이 용어의 사용이 리프팅이 의미하는 것에 대한 직관적이고 좋은 지침 이라는 것을 알았습니다 . 서로 다른 상황 사이에 존재하는 유일한 차이점은이 높은 추상화가 실제로 무엇인지입니다.

특히, Viktor는 함수형 프로그래밍의 맥락에서 알려져 있으며,이 맥락에서 리프팅에 대한 시각적으로 다른 해석을 찾을 수 있습니다 . 예를 들어, 값을 functor로 올리거나 모나드 값 (예 : Haskell 's liftM2) 에서 작동하는 함수를 들어 올리는 것 입니다.

"리프트 표현"의 매우 구체적인 예는 f.ex. List(1)또는 이어야합니다 Some(1).


4

이러한 종류의 개념은 일반적으로 구체적인 예를 통해 이해하기가 가장 쉽습니다. 이 Flow API 예제 에서 발췌 한 다음을 고려하십시오 .

Flow(text.split("\\s").toVector).
      // transform
      map(line => line.toUpperCase).
      // print to console (can also use ``foreach(println)``)
      foreach(transformedLine => println(transformedLine)).
      onComplete(FlowMaterializer(MaterializerSettings())) {
        case Success(_) => system.shutdown()
        case Failure(e) =>
          println("Failure: " + e.getMessage)
          system.shutdown()
      }

다음 코드가 필요합니다.

text.split("\\s").toVector.
      map(line => line.toUpperCase).
      foreach(println)

그리고 그것을 Flow문맥 으로 "들어 올립니다" . 이를 통해 알고리즘을 지정하는 데 익숙한 것과 동일한 구문을 사용할 수 있지만, map여러 프로세서 또는 기계에서 병렬로 수행 된 후 foreach(println)해당 출력을 하나의 프로세서로 매끄럽게 수집하여 인쇄합니다.

이것은 모든 유형의 컨텍스트를 감싸는 것을 의미하는 일반적인 용어입니다. 보다 친숙한 또 다른 예는 map단일 요소에서 작동하고 해당 요소 컬렉션에서 작업하는 새로운 컨텍스트로 "리프팅"하는 함수를 사용하는 것입니다. 리프팅은 함수형 프로그래밍에서 보편적으로 사용되며 함수형 코드를 재사용하는 것이 훨씬 쉬운 주된 이유 중 하나입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.