In a partial function implemented with pattern matching, how to make isDefined return false for invalid inputs that can't be included in the case pattern?
For example, I have the following decodeList partial function:
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
}
I want to change the code in a way so that decodeList.isDefinedAt evaluates to false for invalid inputs. For example, for an a that decode(a) evaluates to None ,decodeList.isDefinedAt(Json.Arr(List(a))) should evaluate to false.
Or from another perspective, if I try to include the condition in the case pattern as in the following code, where shall I put the val options = items map decode definition so it can be reusable by both the case pattern and the block?
def decodeList: PartialFunction[Json, List[A]] = {
case Json.Arr(items) if (options forall (_.isDefined)) =>
options map (_.get)
}
You can do this by defining a custom extractor object, e.g.
which isn't particularly convenient, but I don't know a better way.
Of course, I'd suggest actually defining
def decodeList(list: Json): Option[List[A]]which fits better withdecodeand doesn't need such workarounds; thenFunction.unlift(decodeList)if you need aPartialFunction.