Hľadám riešenie preVesmír a všetko “na stránkach spoj.com pomocou Scalaz IO Monad a Stream. Problémom je prepísať malé čísla zo vstupu na výstup a zastaviť spracovanie vstupu po prečítaní čísla 42. Vytvoril som nasledujúce triedy:
import scalaz._, effect._
def ReadInt: IO[Int] = IO {
readInt
}
def PrintInt(i: Int): IO[Unit] = IO {
println(i)
}
def EchoInt: IO[Int] = {
for {
i <- ReadInt
_ <- PrintInt(i)
} yield (i)
}
Nekonečná slučka funguje podľa očakávania:
scala> import Scalaz._
scala> Stream.continually(EchoInt).sequence.unsafePerformIO
12
22
32
42
52
Keď však chcem, aby to skončilo na čísle 42, nedokončí sa tiež:
scala> Stream.continually(EchoInt).sequence.map(_.takeWhile(_ != 42)).unsafePerformIO
12
22
32
42
52
Viem, že tento kód by mal napokon vytlačiť 42 (na rozdiel od vyhlásenia problému), ale chcel som príkladový kód zjednodušiť.
Kde sa mýlim?
odpovede:
1 pre odpoveď č. 1Stream.continually(EchoInt).sequence
opakovanie EchoInt
nekonečné časy, takže váš program je v podstate nekonečná slučka.
Čo chcete urobiť, je dať nejaký druh break
do vašej slučky, ktorá bude analyzovať vstup pri každej iterácii a zastaví slučku, ak sa vstup rovná 42. Nie je break
vo funkčnom programovaní (pretože neexistujú slučky, iba rekurzia), takže rekurzia jednoducho nepokračujete:
import scalaz.syntax.monad._
...
def echoInts: IO[Unit] = {
for {
i <- EchoInt
_ <- echoInts.whenM(i != 42) // Break if i == 42
} yield ()
}
echoInts.unsafePerformIO()