我使用scalaz进行一些验证,在代码中的某处有布尔条件。样本如下所示:
import scalaz._, std.AllInstances._
object Temporary {
def validate(x: Int): scalaz.Validation[List[String], Boolean] = {
try {
if (x < 10) {
scalaz.Success(true)
} else {
throw new RuntimeException("why oh why")
}
} catch {
case e: Throwable => scalaz.Failure(List(e.getMessage))
}
}
def main(args: Array[String]) {
val x = validate(1) +++ validate(10)
println(x)
val y = List(1,2,4,10).map(validate(_)).reduce(_ +++ _)
println(y)
}
}
我遇到了编译错误。
Error:(21, 25) could not find implicit value for parameter M1: scalaz.Semigroup[Boolean]
val x = validate(1) +++ validate(10)
^
我无法弄清楚如何修复此错误。有什么指针吗?
修改
感谢@Travis Brown的回答,以下是修复此示例的内容。我在对象
中添加了这两行 import scalaz.Semigroup, scalaz.std.anyVal.booleanInstance.conjunction
implicit val booleanSemigroup: Semigroup[Boolean] = conjunction
现在它提供了正确的验证:
Failure(List(why oh why))
Failure(List(why oh why))
太酷了!
答案 0 :(得分:8)
Semigroup[Boolean]
。它确实提供了Conjunction
和Disjunction
标记,如果将标记添加到Boolean
值的静态类型(没有运行时开销),则可以获取指定的实例操作:
import scalaz.{ @@, Validation }
import scalaz.Tags.Conjunction
object Temporary {
def validate(x: Int): Validation[List[String], Boolean @@ Conjunction] = {
try {
if (x < 10) {
scalaz.Success(Conjunction(true))
} else {
throw new RuntimeException("why oh why")
}
} catch {
case e: Throwable => scalaz.Failure(List(e.getMessage))
}
}
def main(args: Array[String]) {
val x = validate(1) +++ validate(10)
println(x)
val y = List(1,2,4,10).map(validate(_)).reduce(_ +++ _)
println(y)
}
}
如果你真的,真的想选择其中一个操作作为布尔的 半群操作,你可以这样做:
import scalaz.Semigroup, scalaz.std.anyVal.booleanInstance.conjunction
implicit val booleanSemigroup: Semigroup[Boolean] = conjunction
然后:
scala> import scalaz.syntax.semigroup._
import scalaz.syntax.semigroup._
scala> true |+| false
res1: Boolean = false
但这与Scalaz哲学有些不一致。