2014-12-18 16 views
6

Bazı scalaz akışlı dokümanlardan bir örnek alalım, ancak teorik bir dönüşle. Scalaz akışlarında Görevden günlüğe kaydetme ve görmezden gelme

import scalaz.stream._ 
import scalaz.concurrent.Task 

val converter: Task[Unit] = 
    io.linesR("testdata/fahrenheit.txt") 
    .filter(s => !s.trim.isEmpty && !s.startsWith("//")) 
    .map(line => fahrenheitToCelsius(line.toDouble).toString) 
    .intersperse("\n") 
    .pipe(text.utf8Encode) 
    .to(io.fileChunkW("testdata/celsius.txt")) 
    .run 

// at the end of the universe... 
val u: Unit = converter.run 

Bu durumda dosya çok iyi olmayan bazı çift dize içerebilir ve fahrenheitToCelsius bazı NumberFormatException atar. Bu durumda, belki de bu hatayı günlüğe kaydetmek ve daha fazla akış işlemi için göz ardı etmek istiyoruz. Bunu yapmanın deyimsel yolu nedir? Bazı örnekler gördüm, ancak genellikle collectFrom akışı.

+0

değil adımları tekrarlayın. Scalaz ile yapabilirsiniz, ancak, başarısız haritalama ve durumda 'Try' kullanmak hatayı yol giriş yapabilirsiniz (muhtemelen bu şekilde: https://github.com/scalaz/scalaz-stream/blob/master/src/test/scala/scalaz/stream/examples/WritingAndLogging.scala#L63). –

cevap

3

Sen \/ve ek işlem Muhtemelen Scalaz için çok deyimsel

def fahrenheitToCelsius(line: String): Throwable \/ String = 
    \/.fromTryCatchNonFatal { 
     val fahrenheit = line.toDouble 
     val celsius = fahrenheit // replace with real convert 
     celsius.toString 
    } 

    def collectSome[T]: PartialFunction[Option[T], T] = { 
    case Some(v) => v 
    } 

    def logThrowable[T]: PartialFunction[Throwable \/ T, Option[T]] = { 
    case -\/(err) => 
     err.printStackTrace() 
     None 
    case \/-(v) => Some(v) 
    } 

    val converter: Task[Unit] = 
    io.linesR("testdata/fahrenheit.txt") 
     .filter(s => !s.trim.isEmpty && !s.startsWith("//")) 
     .map(fahrenheitToCelsius) 
     .map(logThrowable) 
     .collect(collectSome) 
     .intersperse("\n") 
     .pipe(text.utf8Encode) 
     .to(io.fileChunkW("testdata/celsius.txt")) 
     .run 
+0

Tamam, bu yüzden belirli İstisnalarda işlem yapmak için belirtilebilecek bir çalıştırma/deneme çalıştırıcısı veya genel bir işleyici yok mu? Ayrıca, bu durumda .map (collectCome) 'ın' .collect (collectSome) 'olması gerektiğini düşünüyorum. – kareblak

+0

varsayılan işlem ilk istisnada başarısız olur, ancak anlıyorum, hepsini günlüğe kaydetmek istediğinizden, böylece her adımda başarısız olabilecek istisnaları yakalamanız gerekir. evet, bu bir yazım hatası, toplanması gerekir (topla) –

+0

Evet, özellikle okunan veri üzerinde herhangi bir kontrolün olmaması ve skallaz-akışları için, özellikle okunan IO okumaları için çok kullanışlıdır. veri. Bu bir akış - bazı durumlarda sadece bozuk şeyleri atmak istiyorsun. Ama cevap gerçekten de kaplıyor. – kareblak

İlgili konular