복붙노트

[SCALA] 스칼라에서, 왜 부분적으로 명시 적으로 인수 유형을 지정하지 않고 기능을 적용 할 수 없습니다?

SCALA

스칼라에서, 왜 부분적으로 명시 적으로 인수 유형을 지정하지 않고 기능을 적용 할 수 없습니다?

당신이 (f는 세 개의 인수로 함수) 기대 이것은, 익명 함수를 생성합니다

f(_, _, _)

이 대신 "없는 매개 변수 유형"오류를주고, 컴파일되지 않는 이유를 내가 이해하지 못하는 것은 :

f(_, _, 27)

대신, 명시 적으로 밑줄의 유형을 지정해야합니다. 이 함수 f의 매개 변수 유형이 무엇인지 알고 주어진을 추론 할 수 스칼라하지 않나요?

해결법

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

    1.아래 참조는 스칼라 언어 사양에 있습니다

    아래 참조는 스칼라 언어 사양에 있습니다

    다음과 같은 방법을 고려하십시오

    def foo(a: Int, b: Int) = 0
    

    에타 확장 타입의 값 (INT, INT)로 변환이 가능 => 지능. 이 확장은 경우에 호출된다 :

    A) _ 인수 목록 대신에 사용된다 (방법 값 (§6.7))

    val f = foo _
    

    b) 인수 목록을 생략하고, 표현 형태는 기능 타입 (§6.25.2)은 기대 값 :

    val f: (Int, Int) => Int = foo
    

    다) 각 인수는 ( '익명 함수에 대한 자리 표시 자 구문'의 특별한 경우 (§6.23) _입니다)

    val f = foo(_, _)   
    

    표현, foo는 (_, 1) 에타 확장을 충족하지 않는다; 단지 (a) => foo는 (a, 1) (§6.23)으로 확장된다. 지능 : 보통 형식 유추는 것을 알아 내려고 시도하지 않습니다.

  2. ==============================

    2.당신이 일부 응용 프로그램에 대해 생각하는 경우에, 나는이 (당신이 하나를 가지고 반면에) 여러 매개 변수 목록 만 가능하다고 생각 :

    당신이 일부 응용 프로그램에 대해 생각하는 경우에, 나는이 (당신이 하나를 가지고 반면에) 여러 매개 변수 목록 만 가능하다고 생각 :

    def plus(x: Int)(y: Int) = x + y //x and y in different parameter lists
    
    val plus10 = plus(10) _ //_ indicates partial application
    
    println(plus10(2)) //prints 12
    

    내가 구문의 완전 몰랐던 것처럼 설명하지만 귀하의 예는 재미 있고 당신이 하나의 매개 변수 목록과 일부 응용 프로그램을 할 수 있습니다 나타납니다 :

    scala> def plus2(x: Int, y: Int) = x + y
    plus2: (x: Int,y: Int)Int
    
    scala> val anon = plus2(_,_)
    anon: (Int, Int) => Int = <function2>
    
    scala> anon(3, 4)
    res1: Int = 7
    

    그래서 컴파일러는 명확 유형 지능을 추론 할 수있다!

    scala> val anon2 = plus2(20,_)
    <console>:5: error: missing parameter type for expanded function ((x$1) => plus2(20, x$1))
           val anon2 = plus2(20,_)
                                ^
    

    흠, 이상한! 나는 하나의 매개 변수 목록과 일부 응용 프로그램을 할 수있을 것 같지 않습니다. 내가 두 번째 매개 변수의 유형을 선언하는 경우 그러나, 나는 부분 응용 프로그램을 가질 수 있습니다!

    scala> val anon2 = plus2(20,_: Int)
    anon2: (Int) => Int = <function1>
    
    scala> anon2(24)
    res2: Int = 44
    

    편집 - 내가 관찰 할 것 한 가지는 다음 두 쇼트닝은 동일 것처럼이 경우는 이것이 "일부 응용 프로그램"하지만 더 "함수 포인터"와 같은 아니라는 것을 좀 더 분명 보인다이다

    val anon1 = plus2(_,_)
    val anon2 = plus2 _
    
  3. ==============================

    3.나는 오버로드가 불가능 유형을 추론 할 수있는 컴파일러 수 있기 때문에 생각 :

    나는 오버로드가 불가능 유형을 추론 할 수있는 컴파일러 수 있기 때문에 생각 :

    scala> object Ashkan { def f(a:Int,b:Int) = a; def f(a:Int,b:String) = b; }
    defined object Ashkan
    
    scala> Ashkan.f(1,2)
    res45: Int = 1
    
    scala> Ashkan.f(1,"Ashkan")
    res46: String = Ashkan
    
    scala> val x= Ashkan.f _
    <console>:11: error: ambiguous reference to overloaded definition,
    both method f in object Ashkan of type (a: Int, b: String)String
    and  method f in object Ashkan of type (a: Int, b: Int)Int
    match expected type ?
           val x= Ashkan.f _
                         ^
    
    scala> val x= Ashkan.f(_,_)
    <console>:11: error: missing parameter type for expanded function ((x$1, x$2) => Ashkan.f(x$1, x$2))
           val x= Ashkan.f(_,_)
                           ^
    <console>:11: error: missing parameter type for expanded function ((x$1: <error>, x$2) => Ashkan.f(x$1, x$2))
           val x= Ashkan.f(_,_)
                             ^
    
    scala> val x= Ashkan.f(_,"Akbar")
    <console>:11: error: missing parameter type for expanded function ((x$1) => Ashkan.f(x$1, "Akbar"))
           val x= Ashkan.f(_,"Akbar")
                           ^
    
    scala> val x= Ashkan.f(1,_)
    <console>:11: error: missing parameter type for expanded function ((x$1) => Ashkan.f(1, x$1))
           val x= Ashkan.f(1,_)
                             ^
    
    scala> val x= Ashkan.f(1,_:String)
    x: String => String = <function1>
    
  4. ==============================

    4.나는 이것이 원래 메서드 호출을 지시 익명 함수의 생성을 포함하기 때문에이 모든 코드 변환에서 발생하는 국경 사례 중 하나입니다 생각합니다. 유형은 외부 익명 함수의 인수입니다. 에 - 사실, 당신은 하위 유형 즉를 지정할 수 있습니다

    나는 이것이 원래 메서드 호출을 지시 익명 함수의 생성을 포함하기 때문에이 모든 코드 변환에서 발생하는 국경 사례 중 하나입니다 생각합니다. 유형은 외부 익명 함수의 인수입니다. 에 - 사실, 당신은 하위 유형 즉를 지정할 수 있습니다

    val f = foo(_: Nothing, 1) 
    

    심지어이 컴파일 것

  5. from https://stackoverflow.com/questions/2363013/in-scala-why-cant-i-partially-apply-a-function-without-explicitly-specifying-i by cc-by-sa and MIT license