복붙노트

[SCALA] 스칼라에서 무두질의 두 가지 방법; 각 유스 케이스는 무엇인가?

SCALA

스칼라에서 무두질의 두 가지 방법; 각 유스 케이스는 무엇인가?

나는 유지 스칼라 스타일 가이드의 여러 파라미터 목록 주위에 토론을하고있다. 나는 무두질의 두 가지 방법이 있다는 것을 깨닫게 한, 나는 유스 케이스가 무엇인지 궁금하네요 :

def add(a:Int)(b:Int) = {a + b}
// Works
add(5)(6)
// Doesn't compile
val f = add(5)
// Works
val f = add(5)_
f(10) // yields 15

def add2(a:Int) = { b:Int => a + b }
// Works
add2(5)(6)
// Also works
val f = add2(5)
f(10) // Yields 15
// Doesn't compile
val f = add2(5)_

그들은 분명하지 않을 때 스타일 가이드는 잘못이가 동일한 의미한다. 두 번째 형태는 당신이 필요로하지 않기 때문에 사용하기 쉽게 틀림없이하지만 "에 의해 - 더 - 책"태닝, 그것은 (아직 첫 번째 양식과 매우 유사되지 않은 상태에서 가이드는, 생성 카레 기능에 대한 지점을 만들려고 노력하고, _)

이 양식을 사용하는 것과, 다른 이상 한 형태를 사용하는 경우에 대한 합의는 무엇인가?

해결법

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

    1.여러 매개 변수 섹션 방법은 다음 섹션에서 인수에 대한 예상 유형을 제공 할 것입니다 형식 인수를 유추 할 첫 번째 섹션에서 매개 변수를 사용하여, 지역 형식 유추를 지원하는 데 사용할 수 있습니다. 이것의 정식 예는 표준 라이브러리에 foldLeft.

    여러 매개 변수 섹션 방법은 다음 섹션에서 인수에 대한 예상 유형을 제공 할 것입니다 형식 인수를 유추 할 첫 번째 섹션에서 매개 변수를 사용하여, 지역 형식 유추를 지원하는 데 사용할 수 있습니다. 이것의 정식 예는 표준 라이브러리에 foldLeft.

    def foldLeft[B](z: B)(op: (B, A) => B): B
    
    List("").foldLeft(0)(_ + _.length)
    

    이 경우이 같은 기록했다 :

    def foldLeft[B](z: B, op: (B, A) => B): B
    

    하나는 더 명시 적 유형을 제공 할 것입니다 :

    List("").foldLeft(0, (b: Int, a: String) => a + b.length)
    List("").foldLeft[Int](0, _ + _.length)
    

    여러 매개 변수 섹션 방법에 대한 또 다른 용도는 언어 구조처럼 보이는 API를 만드는 것입니다. 호출자는 대신 괄호 괄호를 사용할 수 있습니다.

    def loop[A](n: Int)(body: => A): Unit = (0 until n) foreach (n => body)
    
    loop(2) {
       println("hello!")
    }
    

    N

    카레 함수 (또는 단순히, 함수 반환하는 함수)를보다 용이 N 인수 목록에 적용될.

    val f = (a: Int) => (b: Int) => (c: Int) => a + b + c
    val g = f(1)(2)
    

    이 작은 편의 때때로 가치가있다. 함수는하지만 형식 매개 변수가 될 수 없습니다, 그래서 어떤 경우에는 방법이 필요합니다.

    함수를 리턴하는 하나 개의 매개 변수 부에있어서 두 번째 예는 하이브리드이다.

    또 어디 카레 기능은 유용하다? 여기에 모든 시간을 오는 패턴입니다 :

    def v(t: Double, k: Double): Double = {
       // expensive computation based only on t
       val ft = f(t)
    
       g(ft, k)
    }
    
    v(1, 1); v(1, 2);
    

    우리는 어떻게 결과 F (t)를 공유 할 수 있습니까? 일반적인 솔루션은 V의 벡터화 버전을 제공하는 것입니다 :

    def v(t: Double, ks: Seq[Double]: Seq[Double] = {
       val ft = f(t)
       ks map {k => g(ft, k)}
    }
    

    추한! KS의 시퀀스를 통해 산출 g (F (t), K) 매핑 - 우리는 관계없는 우려 교락했다.

    val v = { (t: Double) =>
       val ft = f(t)
       (k: Double) => g(ft, k)       
    }
    val t = 1
    val ks = Seq(1, 2)
    val vs = ks map (v(t))
    

    우리는 또한 함수를 반환하는 방법을 사용할 수 있습니다. 이 경우는 좀 더 읽기 :

    def v(t:Double): Double => Double = {
       val ft = f(t)
       (k: Double) => g(ft, k)       
    }
    

    우리는 여러 매개 변수 섹션 방법과 동일한 작업을 수행하려고한다면, 우리는 박히 :

    def v(t: Double)(k: Double): Double = {
                    ^
                    `-- Can't insert computation here!
    }
    
  2. ==============================

    2.당신은 기능이 아닌 방법을 카레 수 있습니다. 추가는 방법이다, 그래서 당신은 함수에 _ 강제로의 전환이 필요합니다. ADD2 함수를 반환, 그래서는 _에만 필요 아니라 여기에 이해되지 않는다.

    당신은 기능이 아닌 방법을 카레 수 있습니다. 추가는 방법이다, 그래서 당신은 함수에 _ 강제로의 전환이 필요합니다. ADD2 함수를 반환, 그래서는 _에만 필요 아니라 여기에 이해되지 않는다.

    (JVM을의 관점에서 예를 들어) 다른 방법과 기능이 얼마나 고려, 스칼라는 꽤 좋은 직장 그들 사이의 경계를 모호하게하고 대부분의 경우에 "옳은 일을"일을 수행하지만 차이가있다, 때때로 당신은 단지 필요 그것에 대해 알아야 할 사항.

  3. ==============================

    3.(: 지능 A) (B : int)를 : 나는 내가 데프 추가로 것을 추가하는 경우의 차이점을 파악하는 데 도움이 생각하는 당신은 꽤 많은 단지 만 두 개의 매개 변수는 두 개의 매개 변수 목록에 그룹화되어 두 개의 매개 변수와 메소드를 정의에서 Int (참조 의 결과 다른 의견에서 해당). 사실, 그 방법은 지금까지 자바 (안 스칼라!)와 같은 우려 (INT A,를 int)를 추가하는 int된다. 추가 쓸 때 (5) _, 즉, 짧은 형태의 단지 기능 문자의 {B : 지능 => 추가 (1) (B)}. 반면에, ADD2와 (A : INT) = {B : 지능 => A + B} 당신은 단지 하나의 매개 변수를 가지고하는 방법을 정의하고 자바에 그것을 할 예정입니다 scala.Function ADD2 (INT가). 당신이 ADD2을 쓸 때 (함수 리터럴 반대) (1) 스칼라에 그냥 일반 메소드 호출이다.

    (: 지능 A) (B : int)를 : 나는 내가 데프 추가로 것을 추가하는 경우의 차이점을 파악하는 데 도움이 생각하는 당신은 꽤 많은 단지 만 두 개의 매개 변수는 두 개의 매개 변수 목록에 그룹화되어 두 개의 매개 변수와 메소드를 정의에서 Int (참조 의 결과 다른 의견에서 해당). 사실, 그 방법은 지금까지 자바 (안 스칼라!)와 같은 우려 (INT A,를 int)를 추가하는 int된다. 추가 쓸 때 (5) _, 즉, 짧은 형태의 단지 기능 문자의 {B : 지능 => 추가 (1) (B)}. 반면에, ADD2와 (A : INT) = {B : 지능 => A + B} 당신은 단지 하나의 매개 변수를 가지고하는 방법을 정의하고 자바에 그것을 할 예정입니다 scala.Function ADD2 (INT가). 당신이 ADD2을 쓸 때 (함수 리터럴 반대) (1) 스칼라에 그냥 일반 메소드 호출이다.

    또한 추가 기능이 있습니다주의 즉시 모든 매개 변수를 제공하는 경우 ADD2 이상 (잠재적으로) 적은 오버 헤드가 있습니다. 마찬가지로 추가 (5) (6) 막 (5, 6) JVM 레벨에 어떠한 기능 객체가 생성되지 않는 추가 변환한다. 반면에, ADD2 (5) (6) 첫번째 (6) 그에 적용 호출 후 5 둘러싸는 Function 객체를 만든 것입니다.

  4. from https://stackoverflow.com/questions/4915027/two-ways-of-currying-in-scala-whats-the-use-case-for-each by cc-by-sa and MIT license