Supponiamo che esista una sequenza a[i] = f(a[i-1], a[i-2], ... a[i-k])
. Come lo codificheresti usando streams
in Scala?Sequenza con flussi in Scala
risposta
Sarà possibile generalizzarlo per ogni k, utilizzando una matrice per a
e un altro parametro k
e avendo, f.i., la funzione con un parametro rest...
.
def next(a1:Any, ..., ak:Any, f: (Any, ..., Any) => Any):Stream[Any] {
val n = f(a1, ..., ak)
Stream.cons(n, next(a2, ..., n, f))
}
val myStream = next(init1, ..., initk)
al fine di avere il 1000 fanno next.drop(1000)
Un aggiornamento per mostrare come questo potrebbe essere fatto con varargs. Fate attenzione che non v'è alcun controllo arity per la funzione passata:
object Test extends App {
def next(a:Seq[Long], f: (Long*) => Long): Stream[Long] = {
val v = f(a: _*)
Stream.cons(v, next(a.tail ++ Array(v), f))
}
def init(firsts:Seq[Long], rest:Seq[Long], f: (Long*) => Long):Stream[Long] = {
rest match {
case Nil => next(firsts, f)
case x :: xs => Stream.cons(x,init(firsts, xs, f))
}
}
def sum(a:Long*):Long = {
a.sum
}
val myStream = init(Seq[Long](1,1,1), Seq[Long](1,1,1), sum)
myStream.take(12).foreach(println)
}
Come si ottengono gli iniziali 'k'elementi? – huitseeker
Non fa parte della domanda, ho presunto che siano conosciuti. Come per Fibonacci, si impostano i primi due come 0 e 1. –
@andypetrella sì, hai ragione, presumo che i primi elementi di 'k' siano noti. – Michael
Purtroppo, non possiamo generalizzare su numero e al sicuro al tempo stesso tipo. Quindi dovremo fare tutto manualmente:
def seq2[T, U](initials: Tuple2[T, T]) = new {
def apply(fun: Function2[T, T, T]): Stream[T] = {
initials._1 #::
initials._2 #::
(apply(fun) zip apply(fun).tail).map {
case (a, b) => fun(a, b)
}
}
}
E arriviamo def fibonacci = seq2((1, 1))(_ + _)
.
def seq3[T, U](initials: Tuple3[T, T, T]) = new {
def apply(fun: Function3[T, T, T, T]): Stream[T] = {
initials._1 #::
initials._2 #::
initials._3 #::
(apply(fun) zip apply(fun).tail zip apply(fun).tail.tail).map {
case ((a, b), c) => fun(a, b, c)
}
}
}
def tribonacci = seq3((1, 1, 1))(_ + _ + _)
... e fino a 22.
Spero che il modello è sempre chiaro in qualche modo. (Potremmo, naturalmente, migliorare e scambiare la tupla initials
con argomenti separati.Questo ci risparmia un paio di parentesi più tardi quando lo usiamo.) Se un giorno, in futuro, arriverà il linguaggio macro di Scala, si spera che sarà più facile da definire.
Hmm, il 'def's dovrebbe essere' lazy val's piuttosto. – Debilski
È OK? (a [i] = f (a [ik], a [i-k + 1], ... a [i-1]) anziché a [i] = f (a [i-1], a [i-2], ... una [ik]), dal momento che preferisco in questo modo)
/**
Generating a Stream[T] by the given first k items and a function map k items to the next one.
*/
def getStream[T](f : T => Any,a : T*): Stream[T] = {
def invoke[T](fun: T => Any, es: T*): T = {
if(es.size == 1) fun.asInstanceOf[T=>T].apply(es.head)
else invoke(fun(es.head).asInstanceOf[T => Any],es.tail :_*)
}
Stream.iterate(a){ es => es.tail :+ invoke(f,es: _*)}.map{ _.head }
}
ad esempio, il seguente codice per generare la sequenza di Fibonacci.
scala> val fn = (x: Int, y: Int) => x+y
fn: (Int, Int) => Int = <function2>
scala> val fib = getStream(fn.curried,1,1)
fib: Stream[Int] = Stream(1, ?)
scala> fib.take(10).toList
res0: List[Int] = List(1, 1, 2, 3, 5, 8, 13, 21, 34, 55)
Il codice seguente può generare una sequenza {un} dove a1 = 1, a2 = 2, a3 = 3, a (n + 3) = a (n) + 2a (n + 1) + 3a (n + 2).
scala> val gn = (x: Int, y: Int, z: Int) => x + 2*y + 3*z
gn: (Int, Int, Int) => Int = <function3>
scala> val seq = getStream(gn.curried,1,2,3)
seq: Stream[Int] = Stream(1, ?)
scala> seq.take(10).toList
res1: List[Int] = List(1, 2, 3, 14, 50, 181, 657, 2383, 8644, 31355)
la risposta breve, che si sta probabilmente cercando, è un modello per definire la Stream
una volta che avete fissato un prescelto k
per l'arietà di f
(cioè si dispone di un tipo fisso per f). Il seguente modello ti dà un che n
-esimo elemento è il termine a[n]
della sequenza:
def recStreamK [A](f : A ⇒ A ⇒ ... A) (x1:A) ... (xk:A):Stream[A] =
x1 #:: recStreamK (f) (x2)(x3) ... (xk) (f(x1)(x2) ... (xk))
(di credito: è molto vicino al answer di andy Petrella, tranne che gli elementi iniziali sono impostati correttamente, e di conseguenza il rango nel flusso partite che nella sequenza)
Se voglio generalizzare su k
, questo è possibile in modo sicuro per il tipo (con controllo di arity) in Scala, usando impliciti di sovrapposizione con priorità. Il codice (~80 linee) è disponibile sotto forma di elenco here.Temo di essere un po 'trascinato e lo ho spiegato come un dettagliato post sul blog there.
- 1. Per ciclo in scala senza sequenza?
- 2. Come si consuma flussi secondari raggruppati con mapAsync in Akka flussi
- 3. Come utilizzare infiniti flussi Scala come origine in Spark Streaming?
- 4. Scala sequenza futura e gestione del timeout
- 5. Elaborazione funzionale di flussi Scala senza errori OutOfMemory
- 6. Cython: lavorare con C++ flussi
- 7. modulo nodo gulp-order con flussi uniti
- 8. Flussi di muting in Android
- 9. Mappa one-to-one con flussi Java
- 10. Come devo sommare qualcosa con i flussi?
- 11. Relazioni nidificate con Sequenza
- 12. Differenza tra flussi java 8 e flussi paralleli
- 13. Do Java 8 flussi paralleli utilizzano lo stesso filo per una sequenza
- 14. .con alternativa in scala
- 15. In che modo concatenare i flussi con pigrizia?
- 16. Posso demultiplex i flussi?
- 17. Collegare una sequenza con un'identità in hsqldb
- 18. Flussi crittografati OpenSSL
- 19. GNU parallelo con sequenza variabile?
- 20. Genera sequenza con valore passo
- 21. Affettare Scala Scala con tupla
- 22. C# utilizzando i flussi
- 23. Sequenza infinita con elementi ripetuti
- 24. Come mai "Effect" sigilla solo due in-flussi, invece di tutti i flussi?
- 25. Casi di utilizzo per i flussi reattivi utilizzando i flussi 9 di Java in Servlet?
- 26. Prodotto cartesiano di flussi in Java 8 come flusso (utilizzando solo flussi)
- 27. Test dei flussi di lavoro in Django
- 28. arg max in Java 8 flussi?
- 29. Costruttori in scala con varargs
- 30. È foreach by-definition garantito per iterare la collezione soggetto in sequenza in Scala?
Sto cercando di capire le regole della sequenza. Cos'è 'k'? Cos'è 'a [0]' (il primo elemento nel flusso)? Cos'è 'a [1]'? – toddsundsted
@toddsundsted Supponiamo che conosca i primi elementi 'k' della sequenza: a [0], a [1], ..., a [1]. Ora voglio calcolare 'a [n]' per 'n'>' k' usando la funzione 'f'. – Michael