ここにいくつかの便利なものがあります:
def sysValue(prop: String) = Option(System.getProperty(prop)) //returns Option[String]
def trySysValue(prop: String) = //returns Either[String, String]
sysValue(prop) map Right getOrElse Left("Absent property: " + prop)
次に、その右射影Either
を通じてのモナド構成を使用できます
val batch = //batch is Either[String, (File, File)]
for {
x <- trySysValue("XDir")).right
xf <- dir(x).right
y <- trySysValue("YDir").right
yf <- dir(y).right
}
yield (xf, yf)
どこ:
def dir(s: String) = { //returns Either[String, File]
val f = new File(s)
if (!f.exists()) Left("Does not exist: " + f)
else if (!f.isDir()) Left("Is not a directory: " + f)
else Right(f)
}
の左側Either
はエラー メッセージです。このモナド合成はフェイルファストです。scalazを使用して、すべての失敗を蓄積する構成を実現できます (たとえば、どちらXDir
もYDir
存在しない場合、両方のメッセージが表示されます) 。その場合、コードは次のようになります。 Validation
def trySysValue(prop: String) = //returns Validation[String, String]
sysValue(prop) map Success getOrElse ("Absent property: " + prop).fail
def dir(s: String) = {
val f = new File(s)
if (!f.exists())("Does not exist: " + f).fail
else if (!f.isDir()) ("Is not a directory: " + f).fail
else f.success
}
val batch = //batch is ValidationNEL[String, (File, File)]
(trySysValue("XDir")) flatMap dir).liftFailNel <|*|> (trySysValue("YDir")) flatMap dir).liftFailNel