什么是“抽象”?意思? [英] What does "abstract over" mean?

查看:174
本文介绍了什么是“抽象”?意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Scala文献中,我经常会遇到抽象一词,但我不明白其意图。 例如,马丁·奥德斯基(Martin Odersky)写道

Often in the Scala literature, I encounter the phrase "abstract over", but I don't understand the intent. For example, Martin Odersky writes


您可以将方法(或函数)作为参数传递,也可以将其抽象。您可以将类型指定为参数,也可以抽象

You can pass methods (or "functions") as parameters, or you can abstract over them. You can specify types as parameters, or you can abstract over them.

作为另一个示例,在弃用观察者模式 论文,

As another example, in the "Deprecating the Observer Pattern" paper,


事件流的后果是一流的价值是我们可以提取

我读过一阶泛型抽象于类型,而monads抽象于类型构造函数。而且,我们在蛋糕图案纸。引用许多这样的示例之一:

I have read that first order generics "abstract over types", while monads "abstract over type constructors". And we also see phrases like this in the Cake Pattern paper. To quote one of many such examples:


抽象类型成员提供了灵活的方法来抽象抽象组件类型

Abstract type members provide flexible way to abstract over concrete types of components.

即使是相关的堆栈溢出问题也使用此术语。 不能在参数化类型上本质上抽象...

Even relevant stack overflow questions use this terminology. "can't existentially abstract over parameterized type..."

那么……抽象到底是什么意思?

So... what does "abstract over" actually mean?

推荐答案

在代数中,就像在日常概念形成中一样,抽象是通过按某些基本特征对事物进行分组并忽略其特定的其他特征来形成的。抽象统一在表示相似之处的单个符号或单词下。我们说我们抽象差异,但这实际上意味着我们正在通过相似性集成

In algebra, as in everyday concept formation, abstractions are formed by grouping things by some essential characteristics and omitting their specific other characteristics. The abstraction is unified under a single symbol or word denoting the similarities. We say that we abstract over the differences, but this really means we're integrating by the similarities.

例如,考虑一个程序,该程序使用数字 1 2 的总和3

For example, consider a program that takes the sum of the numbers 1, 2, and 3:

val sumOfOneTwoThree = 1 + 2 + 3

该程序不是很有趣,因为它不是很抽象。通过将所有数字列表集成在单个符号 ns 中,我们可以提取我们所求和的数字:

This program is not very interesting, since it's not very abstract. We can abstract over the numbers we're summing, by integrating all lists of numbers under a single symbol ns:

def sumOf(ns: List[Int]) = ns.foldLeft(0)(_ + _)

我们也不在乎它也是一个列表。 List是一个特定的类型构造函数(接受一个类型并返回一个类型),但是我们可以通过指定我们想要的基本特征(可以折叠)来抽象该类型构造函数:

And we don't particularly care that it's a List either. List is a specific type constructor (takes a type and returns a type), but we can abstract over the type constructor by specifying which essential characteristic we want (that it can be folded):

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)

我们可以为 List 隐含 Foldable 实例我们可以折叠的东西。

And we can have implicit Foldable instances for List and any other thing we can fold.

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))

此外,我们可以抽象操作和操作数的类型:

What's more, we can abstract over both the operation and the type of the operands:

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)

现在我们有了一些通用的东西。假设我们可以证明 F <,方法 mapReduce 将折叠任何 F [A] / code>是可折叠的,并且 A 是一个monoid或可以映射为一个。例如:

Now we have something quite general. The method mapReduce will fold any F[A] given that we can prove that F is foldable and that A is a monoid or can be mapped into one. For example:

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)

我们已经抽象了 monoid和可折叠产品。

We have abstracted over monoids and foldables.

这篇关于什么是“抽象”?意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆