В алгебре, как и при формировании повседневных понятий, абстракции образуются путем группирования вещей по некоторым существенным характеристикам и исключения их конкретных других характеристик. Абстракция объединяется одним символом или словом, обозначающим сходство. Мы говорим, что абстрагируемся от различий, но на самом деле это означает, что мы интегрируемся посредством сходства.
Например, рассмотрим программу , которая принимает суммы чисел 1
, 2
и 3
:
val sumOfOneTwoThree = 1 + 2 + 3
Эта программа не очень интересна, так как не очень абстрактна. Мы можем абстрагироваться от суммируемых чисел, объединив все списки чисел под одним символом ns
:
def sumOf(ns: List[Int]) = ns.foldLeft(0)(_ + _)
И нас не особо волнует, что это список. Список - это конкретный конструктор типа (принимает тип и возвращает тип), но мы можем абстрагироваться от конструктора типа, указав, какую важную характеристику мы хотим (что его можно складывать):
trait Foldable[F[_]] {
def foldl[A, B](as: F[A], z: B, f: (B, A) => B): B
}
def sumOf[F[_]](ns: F[Int])(implicit ff: Foldable[F]) =
ff.foldl(ns, 0, (x: Int, y: Int) => x + y)
И у нас могут быть неявные Foldable
экземпляры List
и все, что мы можем сворачивать.
implicit val listFoldable = new Foldable[List] {
def foldl[A, B](as: List[A], z: B, f: (B, A) => B) = as.foldLeft(z)(f)
}
val sumOfOneTwoThree = sumOf(List(1,2,3))
Более того, мы можем абстрагироваться как от операции, так и от типа операндов:
trait Monoid[M] {
def zero: M
def add(m1: M, m2: M): M
}
trait Foldable[F[_]] {
def foldl[A, B](as: F[A], z: B, f: (B, A) => B): B
def foldMap[A, B](as: F[A], f: A => B)(implicit m: Monoid[B]): B =
foldl(as, m.zero, (b: B, a: A) => m.add(b, f(a)))
}
def mapReduce[F[_], A, B](as: F[A], f: A => B)
(implicit ff: Foldable[F], m: Monoid[B]) =
ff.foldMap(as, f)
Теперь у нас есть кое-что довольно общее. Метод mapReduce
сворачивает любое F[A]
данное, что мы можем доказать, что F
он складывается и A
является моноидом или может быть отображен в один. Например:
case class Sum(value: Int)
case class Product(value: Int)
implicit val sumMonoid = new Monoid[Sum] {
def zero = Sum(0)
def add(a: Sum, b: Sum) = Sum(a.value + b.value)
}
implicit val productMonoid = new Monoid[Product] {
def zero = Product(1)
def add(a: Product, b: Product) = Product(a.value * b.value)
}
val sumOf123 = mapReduce(List(1,2,3), Sum)
val productOf456 = mapReduce(List(4,5,6), Product)
Мы абстрагировались от моноидов и складных объектов.
Set
или какой-нибудь другой складной тип. Пример сString
конкатенацией и тоже был бы довольно крутым.В первом приближении способность «абстрагироваться от чего-либо» означает, что вместо того, чтобы использовать это что-то напрямую, вы можете сделать это параметром или иным образом использовать это «анонимно».
Scala позволяет абстрагироваться от типов, позволяя классам, методам и значениям иметь параметры типа, а значениям - абстрактные (или анонимные) типы.
Scala позволяет абстрагироваться от действий, позволяя методам иметь параметры функций.
Scala позволяет абстрагироваться от функций, позволяя определять типы структурно.
Scala позволяет абстрагироваться от параметров типа, разрешая параметры типа более высокого порядка.
Scala позволяет абстрагироваться от шаблонов доступа к данным, позволяя создавать экстракторы.
Scala позволяет вам абстрагироваться от «вещей, которые можно использовать как что-то еще», разрешая неявные преобразования в качестве параметров. Haskell делает то же самое с классами типов.
Scala (пока) не позволяет абстрагироваться от классов. Вы не можете передать класс чему-либо, а затем использовать этот класс для создания новых объектов. Другие языки допускают абстракцию над классами.
(«Монады абстрагируются над конструкторами типов» истинно только в очень ограничительном смысле. Не зацикливайтесь на этом, пока не наступит момент «Ага! Я понимаю монады !!».)
Способность абстрагироваться от некоторых аспектов вычислений - это в основном то, что позволяет повторно использовать код и создавать библиотеки функциональности. Scala позволяет абстрагироваться от многих других вещей, чем более распространенные языки, и библиотеки в Scala могут быть соответственно более мощными.
источник
Manifest
или даже aClass
и использовать отражение для создания экземпляров новых объектов этого класса.Абстракция - это своего рода обобщение.
http://en.wikipedia.org/wiki/Abstraction
Не только в Scala, но и во многих языках мира необходимы такие механизмы для уменьшения сложности (или, по крайней мере, для создания иерархии, которая разделяет информацию на более простые для понимания части).
Класс - это абстракция над простым типом данных. Это что-то вроде базового типа, но на самом деле их обобщает. Таким образом, класс - это больше, чем простой тип данных, но у него много общего.
Когда он говорит «абстрагирование», он имеет в виду процесс, с помощью которого вы обобщаете. Итак, если вы абстрагируетесь от методов как параметров, вы обобщаете процесс этого. например, вместо передачи методов функциям вы можете создать какой-то обобщенный способ их обработки (например, не передавать методы вообще, а создать специальную систему для работы с этим).
В данном случае он конкретно имеет в виду процесс абстрагирования проблемы и создания решения проблемы, похожего на опцию. У C очень небольшая способность к абстрагированию (вы можете это сделать, но он очень быстро становится беспорядочным, и язык напрямую не поддерживает это). Если вы написали это на C ++, вы могли бы использовать концепции oop, чтобы уменьшить сложность проблемы (ну, это такая же сложность, но концептуализация в целом проще (по крайней мере, когда вы научитесь мыслить в терминах абстракций)).
например, если мне нужен особый тип данных, который был бы похож на int, но, скажем так, ограниченно, я мог бы абстрагироваться от него, создав новый тип, который мог бы использоваться как int, но имел те свойства, которые мне были нужны. Процесс, который я бы использовал для этого, можно было бы назвать «абстрагированием».
источник
Вот моя узкая интерпретация шоу и рассказа. Это не требует пояснений и работает в REPL.
источник
Другие ответы уже дают хорошее представление о том, какие существуют абстракции. Давайте пройдемся по кавычкам одну за другой и приведем пример:
Передать функцию как параметр: здесь
List(1,-2,3).map(math.abs(x))
явноabs
передается как параметр.map
Сама по себе абстрагируется от функции, которая делает определенную специальную вещь с каждым элементом списка.val list = List[String]()
указывает параметр типа (String). Вы можете написать тип коллекции , которая использует абстрактные элементы типа вместо:val buffer = Buffer{ type Elem=String }
. Одно отличие состоит в том, что вы должны писать «def f(lis:List[String])...
но»def f(buffer:Buffer)...
, поэтому тип элемента во втором методе как бы «скрыт».В Swing событие просто «случается» неожиданно, и вы должны иметь дело с ним здесь и сейчас. Потоки событий позволяют выполнять все работы по подключению и подключению более декларативно. Например, когда вы хотите изменить ответственного слушателя в Swing, вы должны отменить регистрацию старого и зарегистрировать новый, а также знать все кровавые детали (например, проблемы с потоками). С потоками событий источник событий становится вещью, которую вы можете просто передать, что не сильно отличается от потока байтов или символов, следовательно, это более «абстрактная» концепция.
Приведенный выше класс Buffer уже является примером этого.
источник
Ответы выше дают прекрасное объяснение, но, резюмируя его в одном предложении, я бы сказал:
источник