O que é uma "representação levantada"?


12

Acabei de encontrar este termo aqui:

http://www.codemesh.io/codemesh2014/viktor-klang

"Demonstraremos a API do Flow - uma representação levantada - e também uma maneira conectável de transformar a representação levantada na representação de execução - Materialização do fluxo".

Googling não ajudou muito.


leitura recomendada: Discuta este $ {blog}
gnat

11
@gnat, parece que ele não inventou esse termo, não parece uma opinião, não é provável que provoque uma discussão e meu pressentimento é que não será muito amplo (embora pareça matemática).
Den

2
Discuto o significado de "levantado" no contexto do C # aqui: blogs.msdn.com/b/ericlippert/archive/2007/06/27/… - provavelmente os desenvolvedores do Scala estão usando o termo de forma análoga, mas mais moda geral.
Eric Lippert

Respostas:


22

Não estou familiarizado com a API de fluxo.

O termo "levantamento" vem da teoria das categorias. Em linguagens de programação como Haskell ou Scala, uma liftfunção assume uma função A => Be, de alguma forma, executa mágica para que a função levantada F[A] => F[B]possa ser aplicada a um functor ou mônada F[A].

Um exemplo concreto usando o Seqcontêiner de Scala : Suponha que temos uma função def double(x: Int): Int = 2 * xe uma sequência val xs = Seq(1, 2, 3). Não podemos double(xs)devido a tipos incompatíveis. Mas se obtivermos um val doubleSeq = liftToSeq(double), podemos fazer o doubleSeq(xs)que é avaliado como Seq(2, 4, 6). Aqui, liftToSeqpode ser implementado como

def liftToSeq[A, B](f: A => B): (Seq[A] => Seq[B]) =
  (seq: Seq[A]) => seq.map(f)

O Seq(…)construtor também pode ser visto como uma operação de elevação, que eleva os valores 1, 2, 3em uma Seqinstância, permitindo usar abstrações de lista para esses valores.

As mônadas nos permitem encapsular o funcionamento interno de algum tipo, oferecendo uma interface estanque, mas compostável. O uso de uma representação levantada pode facilitar o raciocínio sobre um cálculo. Usar essas abstrações também significa que perdemos o conhecimento das especificidades abstraídas, mas são necessárias para fornecer uma implementação eficiente sob o capô (encontrar uma representação de execução adequada).


4
Essa é uma boa descrição do "levantamento" matemático. Também devemos incluir uma referência à descrição mais formal de levantamento da Wikipedia .
10138 Scott Whitlock

3
Um exemplo talvez mais claro de "levantamento" é o levantamento para tipos anuláveis ​​(ou "opcionais" ou "talvez"). Por exemplo, suponha que você tenha um operador +definido de forma que int + int --> int. O operador levantado para anulável int? + int? --> int?possui a semântica de "se um operando for nulo, a resposta é nula; caso contrário, use o operador não levantado nos valores".
Eric Lippert

@ScottWhitlock Você nem levanta?
helrich

1
@ Frank Eu li o artigo da Wikipedia antes de escrever minha resposta e também não a entendi. Em vez disso, achei o Wiki Haskell sobre levantamento mais acessível. Observe que realmente não temos quatro tipos. Temos quatro tipos concretos, mas apenas três variáveis ​​de tipo: dois tipos Ae B, e um functor Fque é um construtor de tipos.
amon

1
Eu não sou muito aprofundado em tudo isso, mas se Fé um construtor de tipos, então F[A]é um dos tipos construídos. Então, por que é errado falar desses quatro tipos? (dois tipos e um tipo construtor seria igualmente excelentes embora, é claro)
Frank

6

É claro que o termo levantar pode ter significados diferentes, dependendo do contexto.

Na programação genérica , descreve o processo de abstração para o próximo nível superior. Por exemplo, você pode ter dois pedaços de código, um tipo com inte o outro com float. A elevação desse código significaria algo como modelar o método com um tipo genérico Tque funcione para ambos, inte float.

Eu achei esse uso do termo uma boa orientação intuitiva para o que significa elevação . A única diferença que parece existir entre os diferentes contextos é o que realmente é essa abstração mais alta.

Em particular, Viktor é conhecido no contexto da programação funcional e, nesse contexto, você pode encontrar interpretações visivelmente diferentes de elevação lá. Um exemplo é elevar valores em um functor ou elevar funções para trabalhar com valores monádicos (por exemplo, de Haskell liftM2).

Um exemplo muito concreto de uma "representação levantada" poderia, por exemplo, f.ex. ser um List(1), ou um Some(1).


4

Geralmente, esses tipos de conceitos são mais fáceis de entender com um exemplo concreto. Considere o seguinte trecho deste exemplo da API de fluxo :

Flow(text.split("\\s").toVector).
      // transform
      map(line => line.toUpperCase).
      // print to console (can also use ``foreach(println)``)
      foreach(transformedLine => println(transformedLine)).
      onComplete(FlowMaterializer(MaterializerSettings())) {
        case Success(_) => system.shutdown()
        case Failure(e) =>
          println("Failure: " + e.getMessage)
          system.shutdown()
      }

Isso leva o seguinte código:

text.split("\\s").toVector.
      map(line => line.toUpperCase).
      foreach(println)

e "eleva" isso a um Flowcontexto. Isso permite que você use a mesma sintaxe com a qual você está familiarizado para especificar seu algoritmo, mas, nos bastidores, isso mapé feito em paralelo em vários processadores ou até em máquinas; depois, ele foreach(println)coleta a saída de volta para um processador para impressão.

Este é um termo genérico que pode se referir a agrupar qualquer contexto em torno de qualquer tipo. Outro exemplo mais familiar é mappegar uma função que trabalha em um único elemento e a "eleva" ao novo contexto de trabalho em uma coleção desses elementos. O levantamento é onipresente na programação funcional e um dos principais motivos pelos quais é muito mais fácil reutilizar o código funcional.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.