Массив-языки, такие как повторное использование кода в Scala - PullRequest
3 голосов
/ 13 августа 2010

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

Возможно ли этого добитьсявид повторного использования кода в Scala?

Ответы [ 3 ]

5 голосов
/ 13 августа 2010

Это что-то вроде скалала , что вы ищете?

5 голосов
/ 13 августа 2010

Это вполне возможно (я сам это сделал) с соответствующими последствиями, хотя результат не всегда является настолько плавным, как язык, который был разработан с нуля таким образом.

Например,Предположим, вы хотите рассматривать массивы целых чисел как векторы и хотите иметь возможность добавлять их друг к другу и к скалярам.Вы должны определить операцию самостоятельно - Scala не может угадать, что + должно означать для массива.(Хорошая вещь также, потому что * обычно не имеет очевидного поэлементного значения для матриц, и это означает что-то еще, когда дело доходит до свертки!) Вы можете

class ArraysAdd(a: Array[Int]) {
  def +(i: Int) = a.map(_ + i)
  def +(b: Array[Int]) = {
    if (b.length==a.length) (a,b).zipped.map(_ + _).toArray
    else throw new IllegalArgumentException
  }
}
class ScalarAddsToArray(i: Int) {
  def +(a: Array[Int]) = a.map(_ + i)
}
implicit def array2addable(a: Array[Int]) = new ArraysAdd(a)
implicit def scalar2arrayaddable(i: Int) = new ScalarAddsToArray(i)

и затем вы можете выполнить математику для массивов целых чисел:

scala> Array(1,2,3) + 5
res2: Array[Int] = Array(6, 7, 8)

scala> Array(1,7) + Array(3,2)
res3: Array[Int] = Array(4, 9)

scala> 4 + Array(-2,-3,-1)
res4: Array[Int] = Array(2, 1, 3)

Если вы хотите охватить все типы данных, это становится сложнее (вам нужно использовать как минимум дженерики, так и Numeric - или написать генератор кода дляслучаев, которые вам нужны), и для эффективности вы можете захотеть создать собственный класс «матрицы» вместо того, чтобы придерживаться необработанных массивов, которые вы продолжаете упаковывать с дополнительными функциями.

Это охватывает основные операции.Для математических функций, таких как math.sqrt, если вы не против набрать a map sqrt вместо sqrt(a), вам не нужно ничего делать.В противном случае вы можете перегрузить их все сами;утомительно, но затем позволяет вам использовать их прозрачно.

Или вы можете использовать библиотеку, которая уже сделала многое для вас.(Скала - лучший из известных мне кандидатов на матрицы.)

5 голосов
/ 13 августа 2010

Нет никакого реального способа автоматического поднятия операций Scala, поскольку вам потребуется поддержка языков программирования массивов, таких как APL и J. Самая близкая вещь к автоподъему массивов в Scala - это неявные преобразования, и это не так.Совершенно верно.Неявные преобразования в Scala идут противоположным путем, преобразуя цели операций, а не сами операции.Даже в этом случае неявные преобразования Scala не связываются друг с другом, поэтому, даже если бы вы могли поднять скалярную операцию в вектор (а вы не можете), это автоматически не подняло бы ее в двумерный или более высокий массив.

Короче говоря, выполнение вычисления APL / J-ish в Scala будет включать в себя многократное отображение методов «map» и «flatMap», вызываемых явно (а также сложение, уменьшение, сканирование и все остальные).другие обычные подозреваемые).Одним из преимуществ является то, что вы можете кодировать эти операции как для-понимания в Scala, что может дать некоторую замечательную ясность для таких пакетных операций над коллекциями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...