Использование подчеркивания Scala для упрощения синтаксиса функциональных литералов

#scala #lambda #syntax #function-literal #scala-placeholder-syntax

#scala #лямбда #синтаксис #литерал функции #scala-placeholder-синтаксис

Вопрос:

У меня есть следующий код:

 var x = Array(1,3,4,4,1,1,3)
var m = Int.MaxValue
x.foreach((x)=>(m = m min x))
  

Я попытался упростить последнее предложение до:

 x.foreach((m = _ min m))
  

Но интерпретатор говорит:

 scala>  x.foreach((m = _ min m))     
<console>:8: error: missing parameter type for expanded function ((x$1) => x$1.min(m))
    x.foreach((m = _ min m))
                   ^
  

Я попытался более четко указать тип:

 scala>  x.foreach((m = (_:Int) min m))
<console>:8: error: type mismatch;
found   : (Int) => Int
required: Int
    x.foreach((m = (_:Int) min m))
                           ^
  

Мы с компилятором не понимаем друг друга: (

С наилучшими пожеланиями,

Stan

Комментарии:

1. Кажется, = оно ограничивает выражение. Я не ожидал, что это произойдет… И я протестировал код, но он явно не работает, поэтому я удалил свой ответ.

Ответ №1:

Во-первых, обратите внимание, что

 val m = x.min
  

делает то, что вы хотите, как и

 val m = (Int.MaxValue /: x)(_ min _)
  

Я предоставлю вам возможность прочитать больше об этих вещах (метод min для коллекций и свертки; обратите внимание, что это не так быстро, как то, что вы написали).

Проблема в том, что компилятор не понимает, что вы имеете в виду и какими могут быть допустимые типы, когда вы пишете подчеркивание, и когда вы добавляете информацию о типе, он думает, что вы пытаетесь прямо там написать функцию и присвоить ее m . Но, конечно, m это Int , а не функция, поэтому он жалуется.

Просто напишите это явно. Это всего лишь несколько дополнительных символов:

 x.foreach(i => m = m min i)
  

Комментарии:

1. Спасибо, Рекс! Я пытался понять детали упрощения выражений с использованием подчеркивания, больше, чем вычисление минимума. Ваше решение: значение m = (Int.MaxValue /: x)(_ min _), очень аккуратно! Приветствия!