Оператор Scala #› вызывает ошибку компиляции, но не &› - почему?

У меня проблема с выводом типа, и я попросил помощи здесь. Первоначальная проблема была из-за перегрузки. После исправления у меня все еще были проблемы.

Итак, вот код:

class DPipe[ A ]( a: A ) {
  def !>[ B ]( f: A => B ) = Try(f( a ))
  def #>[ B, C ]( f: B => C )(implicit ev: A =:= Try[B]) : Try[C] = a.map(f)
  //def &>[ B, C ]( f: B => C )( implicit ev: A =:= Try[ B ] ) =  a.map( f )
}

object DPipe {
  def apply[ A ]( v: A ) = new DPipe( v )
}

object DPipeOps {
  implicit def toDPipe[ A ]( a: A ): DPipe[ A ] = DPipe( a )
}

А вот и тесты:

object DPipeDebug {

 def main( args: Array[ String ] ) {

    import DPipeOps._

    val r8 = 100.0 !> {x : Double => x / 0.0}  
    println(r8)
    val r9 = r8 #> {x:Double => x* 3.0} 
    println(r9)
    /*
    val r8 = 100.0 !> { x: Double => x / 0.0 }
    println( r8.get )
    val r9 = r8 &> { x: Double => x * 3.0 }
    println( r9 )*/

    val r10 = (100.0 !> {x : Double => x / 0.0}) #> {x:Double => x* 3.0} 
   //val r10 = ( 100.0 !> { x: Double => x / 0.0 } ) &> { x: Double => x * 3.0 }

    val r11 = 100.0 !> {x : Double => x / 0.0} #> {x:Double => x* 3.0} 
    //val r11 = 100.0 !> { x: Double => x / 0.0 } &> { x: Double => x * 3.0     }
  }

}

В нынешнем виде у нас есть следующая ошибка в последней строке кода:

Cannot prove that Double => Double =:= scala.util.Try[Double].
val r11 = 100.0 !> {x : Double => x / 0.0} #> {x:Double => x* 3.0} 
                                           ^

Обратите внимание, что в предпоследней строке кода мне нужно только добавить круглую скобку, чтобы обеспечить левостороннюю ассоциативность (по умолчанию в Scala). Похоже, что оператор #> пытается использовать функцию {x : Double => x / 0.0}, которая действительно является Double.

Однако, если я использую оператор «&>», ошибки не возникает. В приведенном ниже тестовом коде просто переверните комментарии. Итак, мой вопрос, почему это происходит. Это что-то новое для Scala 2.12.0?

ТИА


person user2051561    schedule 24.11.2016    source источник
comment
Не такой уж и новый. См. stackoverflow.com/questions/2922347/   -  person Łukasz    schedule 24.11.2016
comment
@ Лукаш - я не учитывал приоритет оператора. Ослепленный проблемой перегрузки, которая заставила меня рассмотреть ассоциативность операторов. Итак, вот объяснение, которое мне было нужно: # имеет более высокий приоритет, чем ! (по ссылке, которую вы предоставили). Итак, вы можете сделать это ответом, чтобы я мог пометить его как правильный? ТИА.   -  person user2051561    schedule 24.11.2016


Ответы (1)


Проблема в приоритете оператора. Подробнее: Приоритет оператора в Scala

Это зависит от первого символа оператора. # имеет более высокий приоритет, чем !, а ! имеет более высокий приоритет, чем &.

Следовательно, вы получаете

100.0 !> ({x : Double => x / 0.0} #> {x:Double => x* 3.0})

вместо

(100.0 !> {x : Double => x / 0.0}) #> {x:Double => x* 3.0}
person Łukasz    schedule 24.11.2016