2016-01-03 15 views
1

我需要一個組合器,該組合器在成功時運行副作用並在ValidationNel上返回錯誤。在ValidationNel上運行一個副作用並返回錯誤

這是我第一次嘗試:

def runSideEffectAndReturnErrors[E, A](v: ValidationNel[E, A], f: A => Unit) : Seq[E] = v match { 
    case Failure(errors) => errors.list 
    case Success(a) => 
    f(a) 
    Seq.empty[E] 
} 

這裏是第二個。它在運行時可能會有額外的成本,但是我發現它更具可讀性並且可以利用現有的組合器。

def runSideEffectAndReturnErrors[E, A](v: ValidationNel[E, A], f: A => Unit) : Seq[E] = { 
    v.foreach(f) 
    v.fold(_.list, _ => Seq.empty[E]) 
} 

您怎麼看?有沒有更好的辦法 ?

回答

1

這主要是個人喜好的問題,但我發現下面的比任何這些版本的更好一點:

import scalaz._, Scalaz._ 

def RSEaRE[E, A](v: ValidationNel[E, A], f: A => Unit): Seq[E] = 
    v.map(f).fold(_.list.toList, _ => Nil) 

或者:

def RSEaRE[E, A](v: ValidationNel[E, A], f: A => Unit): Seq[E] = 
    v.map(f).swap.map(_.list.toList).getOrElse(Nil) 

或者只是:

def RSEaRE[E, A](v: ValidationNel[E, A], f: A => Unit): Seq[E] = 
    v.fold(_.list.toList, a => { f(a); Nil }) 

這是非常接近你的第一個版本。

(請注意,我使用的是7.2.0-它看起來像你在早期版本,在這種情況下,你不需要toList。)

相關問題