varias superponer studio lineas histogramas graficos graficas scala using tuples

scala - studio - superponer graficas en r



Scala: funciĆ³n "utilizando" (7)

Alguien ya lo ha hecho, se llama Scala ARM .

Desde el readme:

import resource._ for(input <- managed(new FileInputStream("test.txt")) { // Code that uses the input as a FileInputStream }

He definido la función ''usando'' de la siguiente manera:

def using[A, B <: {def close(): Unit}] (closeable: B) (f: B => A): A = try { f(closeable) } finally { closeable.close() }

Puedo usarlo así:

using(new PrintWriter("sample.txt")){ out => out.println("hellow world!") }

ahora tengo curiosidad por cómo definir la función ''usar'' para tomar cualquier número de parámetros y poder acceder a ellos por separado:

using(new BufferedReader(new FileReader("in.txt")), new PrintWriter("out.txt")){ (in, out) => out.println(in.readLIne) }


Desafortunadamente, no hay soporte para listas de parámetros de longitud arbitraria con tipos arbitrarios en Scala estándar.

Es posible que pueda hacer algo como esto con un par de cambios de idioma (para permitir que las listas de parámetros variables se pasen como HLists; consulte here aproximadamente 1/3 de lo que se necesita).

En este momento, lo mejor que puede hacer es hacer lo que Tuple y Function hacen: implementar usando N para la cantidad de N que necesite.

Dos es bastante fácil, por supuesto:

def using2[A, B <: {def close(): Unit}, C <: { def close(): Unit}](closeB: B, closeC: C)(f: (B,C) => A): A = { try { f(closeB,closeC) } finally { closeB.close(); closeC.close() } }

Si necesitas más, probablemente valga la pena escribir algo que genere el código fuente.


Es una buena idea separar el algoritmo de limpieza de la ruta del programa.

Esta solución le permite acumular elementos de cierre en un ámbito.
La limpieza del alcance ocurrirá después de que se ejecute el bloque, o el alcance se puede separar. La limpieza del alcance se puede hacer más tarde.

De esta manera obtenemos la misma conveniencia sin limitarnos a la programación de un solo hilo.

La clase de utilidad:

import java.io.Closeable object ManagedScope { val scope=new ThreadLocal[Scope](); def managedScope[T](inner: =>T):T={ val previous=scope.get(); val thisScope=new Scope(); scope.set(thisScope); try{ inner } finally { scope.set(previous); if(!thisScope.detatched) thisScope.close(); } } def closeLater[T <: Closeable](what:T): T = { val theScope=scope.get(); if(!(theScope eq null)){ theScope.closeables=theScope.closeables.:+(what); } what; } def detatchScope(): Scope={ val theScope=scope.get(); if(theScope eq null) null; else { theScope.detatched=true; theScope; } } } class Scope{ var detatched=false; var closeables:List[Closeable]=List(); def close():Unit={ for(c<-closeables){ try{ if(!(c eq null))c.close(); } catch{ case e:Throwable=>{}; } } } }

El uso:

def checkSocketConnect(host:String, portNumber:Int):Unit = managedScope { // The close later function tags the closeable to be closed later val socket = closeLater( new Socket(host, portNumber) ); doWork(socket); } def checkFutureConnect(host:String, portNumber:Int):Unit = managedScope { // The close later function tags the closeable to be closed later val socket = closeLater( new Socket(host, portNumber) ); val future:Future[Boolean]=doAsyncWork(socket); // Detatch the scope and use it in the future. val scope=detatchScope(); future.onComplete(v=>scope.close()); }


Esta solución no tiene la sintaxis que desea, pero creo que está lo suficientemente cerca :)

def using[A <: {def close(): Unit}, B](resources: List[A])(f: List[A] => B): B = try f(resources) finally resources.foreach(_.close()) using(List(new BufferedReader(new FileReader("in.txt")), new PrintWriter("out.txt"))) { case List(in: BufferedReader, out: PrintWriter) => out.println(in.readLine()) }

Por supuesto, el lado PrintWrter es que tiene que escribir los tipos BufferedReader y PrintWrter en el bloque de uso. Es posible que pueda agregar algo de magia para que solo necesite la List(in, out) mediante el uso de múltiples límites de tipo ORed para el tipo A en uso.

Al definir algunas conversiones implícitas bastante intrincadas y peligrosas, puede evitar tener que escribir la List (y otra forma de evitar la especificación de tipos para los recursos), pero no he documentado los detalles, ya que es una OMI demasiado peligrosa.


Este es un ejemplo que le permite usar la escala para la comprensión como un bloque de administración automática de recursos para cualquier elemento que sea un java.io.Para cierre, pero podría expandirse fácilmente para trabajar con cualquier método con un método cercano.

Este uso parece bastante similar a la declaración de uso y le permite tener fácilmente tantos recursos definidos en un bloque como desee.

object ResourceTest{ import CloseableResource._ import java.io._ def test(){ for( input <- new BufferedReader(new FileReader("/tmp/input.txt")); output <- new FileWriter("/tmp/output.txt") ){ output.write(input.readLine) } } } class CloseableResource[T](resource: =>T,onClose: T=>Unit){ def foreach(f: T=>Unit){ val r = resource try{ f(r) } finally{ try{ onClose(r) } catch{ case e => println("error closing resource") e.printStackTrace } } } } object CloseableResource{ implicit def javaCloseableToCloseableResource[T <: java.io.Closeable](resource:T):CloseableResource[T] = new CloseableResource[T](resource,{_.close}) }


He estado pensando en esto y pensé que podría haber otra forma de resolverlo. Aquí está mi opinión sobre el soporte de "cualquier número" de parámetros (limitado por lo que proporcionan las tuplas):

object UsingTest { type Closeable = {def close():Unit } final class CloseAfter[A<:Product](val x: A) { def closeAfter[B](block: A=>B): B = { try { block(x); } finally { for (i <- 0 until x.productArity) { x.productElement(i) match { case c:Closeable => println("closing " + c); c.close() case _ => } } } } } implicit def any2CloseAfter[A<:Product](x: A): CloseAfter[A] = new CloseAfter(x) def main(args:Array[String]): Unit = { import java.io._ (new BufferedReader(new FileReader("in.txt")), new PrintWriter("out.txt"), new PrintWriter("sample.txt")) closeAfter {case (in, out, other) => out.println(in.readLine) other.println("hello world!") } } }

Creo que estoy reutilizando el hecho de que se han escrito 22 tuplas / clases de productos en la biblioteca ... No creo que esta sintaxis sea más clara que usar el uso anidado (sin juego de palabras), pero fue un rompecabezas interesante.

editar: reemplazó la asignación de val con case (in, out, other) y case (in, out, other) según lo sugerido por retronym.


el uso de tipificación estructural parece un poco excesivo, ya que java.lang.AutoCloseable está predestinado para su uso:

def using[A <: AutoCloseable, B](resource: A)(block: A => B): B = try block(resource) finally resource.close()

O, si prefieres los métodos de extensión:

implicit class UsingExtension[A <: AutoCloseable](val resource: A) extends AnyVal { def using[B](block: A => B): B = try block(resource) finally resource.close() }

usar2 es posible:

def using2[R1 <: AutoCloseable, R2 <: AutoCloseable, B](resource1: R1, resource2: R2)(block: (R1, R2) => B): B = using(resource1) { _ => using(resource2) { _ => block(resource1, resource2) } }

pero todavía soy bastante feo: preferiría simplemente anidar estas declaraciones de uso en el código del cliente.