在模式匹配部分函数中,如何使 isDefined return false 对于不能包含在 case 模式中的无效输入?
In a pattern matching partial function, how to make isDefined return false for invalid inputs that can't be included in the case pattern?
在用模式匹配实现的部分函数中,如何使isDefined
return false
不能包含在case模式中的无效输入?
例如,我有以下 decodeList
部分函数:
case class Arr(items: List[Json]) extends Json
def decode(data: Json): Option[A]
def decodeList: PartialFunction[Json, List[A]] = {
case Json.Arr(items) =>
val options = items map decode
if (options forall (_.isDefined)) options map (_.get)
else throw new Error // the partial function should be undefined here
}
我想以某种方式更改代码,以便 decodeList.isDefinedAt
对无效输入求值为 false。例如,对于 decode(a)
计算为 None
的 a
,decodeList.isDefinedAt(Json.Arr(List(a)))
应计算为 false
.
或者从另一个角度来看,如果我尝试像下面的代码那样在 case 模式中包含条件,我应该把 val options = items map decode
定义放在哪里,这样它就可以被 case 模式和阻止?
def decodeList: PartialFunction[Json, List[A]] = {
case Json.Arr(items) if (options forall (_.isDefined)) =>
options map (_.get)
}
您可以通过定义自定义提取器对象来执行此操作,例如
object Options {
def unapply(items: List[Json]) = Some(items map decode)
}
def decodeList: PartialFunction[Json, List[A]] = {
case Json.Arr(Options(options)) if (options forall (_.isDefined)) =>
options map (_.get)
}
这不是特别方便,但我不知道更好的方法。
当然,我建议实际定义 def decodeList(list: Json): Option[List[A]]
,它更适合 decode
,并且不需要这样的解决方法;然后 Function.unlift(decodeList)
如果你需要 PartialFunction
.
def decodeList(list: Json) = list match {
case Json.Arr(items) =>
val options = items map decode
if (options forall (_.isDefined)) Some(options map (_.get)) else None
case _ => None
}
从技术上讲,您可以像这样直接定义 PartialFunction
来覆盖 isDefinedAt
def decodeList: PartialFunction[Json, List[A]] = new PartialFunction[Json, List[A]] {
override def apply(json: Json): List[A] = json match {
case Json.Arr(items) =>
val options = items map decode
options map (_.get)
}
override def isDefinedAt(json: Json): Boolean = json match {
case Json.Arr(items) =>
val options = items map decode
options forall (_.isDefined)
}
}
然而,这与 isDefinedAt
编译器将由 default 提供的类型不同。
在用模式匹配实现的部分函数中,如何使isDefined
return false
不能包含在case模式中的无效输入?
例如,我有以下 decodeList
部分函数:
case class Arr(items: List[Json]) extends Json
def decode(data: Json): Option[A]
def decodeList: PartialFunction[Json, List[A]] = {
case Json.Arr(items) =>
val options = items map decode
if (options forall (_.isDefined)) options map (_.get)
else throw new Error // the partial function should be undefined here
}
我想以某种方式更改代码,以便 decodeList.isDefinedAt
对无效输入求值为 false。例如,对于 decode(a)
计算为 None
的 a
,decodeList.isDefinedAt(Json.Arr(List(a)))
应计算为 false
.
或者从另一个角度来看,如果我尝试像下面的代码那样在 case 模式中包含条件,我应该把 val options = items map decode
定义放在哪里,这样它就可以被 case 模式和阻止?
def decodeList: PartialFunction[Json, List[A]] = {
case Json.Arr(items) if (options forall (_.isDefined)) =>
options map (_.get)
}
您可以通过定义自定义提取器对象来执行此操作,例如
object Options {
def unapply(items: List[Json]) = Some(items map decode)
}
def decodeList: PartialFunction[Json, List[A]] = {
case Json.Arr(Options(options)) if (options forall (_.isDefined)) =>
options map (_.get)
}
这不是特别方便,但我不知道更好的方法。
当然,我建议实际定义 def decodeList(list: Json): Option[List[A]]
,它更适合 decode
,并且不需要这样的解决方法;然后 Function.unlift(decodeList)
如果你需要 PartialFunction
.
def decodeList(list: Json) = list match {
case Json.Arr(items) =>
val options = items map decode
if (options forall (_.isDefined)) Some(options map (_.get)) else None
case _ => None
}
从技术上讲,您可以像这样直接定义 PartialFunction
来覆盖 isDefinedAt
def decodeList: PartialFunction[Json, List[A]] = new PartialFunction[Json, List[A]] {
override def apply(json: Json): List[A] = json match {
case Json.Arr(items) =>
val options = items map decode
options map (_.get)
}
override def isDefinedAt(json: Json): Boolean = json match {
case Json.Arr(items) =>
val options = items map decode
options forall (_.isDefined)
}
}
然而,这与 isDefinedAt
编译器将由 default 提供的类型不同。