आप पैटर्न मैच में Inl
और Inr
कंस्ट्रक्टर्स उपयोग कर सकते हैं: क्योंकि आप CNil
मामले को संभालने के लिए अगर आप संकलक कि बताने के लिए सक्षम होने के लिए चाहते हैं
import shapeless.{ CNil, Inl, Inr, :+: }
type ListOrString = List[Int] :+: String :+: CNil
def f(a: ListOrString): Int = a match {
case Inl(0 :: second :: Nil) => second
case Inl(first :: Nil) => first
case Inl(Nil) => -1
case Inr(Inl(string)) => string.toInt
}
यह दृष्टिकोण आदर्श नहीं है मैच संपूर्ण-हम है कि यह संभव के लिए यह मामला मैच के लिए नहीं है, लेकिन संकलक नहीं है, तो हम कुछ इस तरह करना है:
def f(a: ListOrString): Int = a match {
case Inl(0 :: second :: Nil) => second
case Inl(first :: Nil) => first
case Inl(Nil) => -1
case Inl(other) => other.sum
case Inr(Inl(string)) => string.toInt
case Inr(Inr(_)) => sys.error("Impossible")
}
मैं भी व्यक्तिगत रूप से सिर्फ appro करने के लिए नेविगेट करने लगता है Inr
और Inl
के साथ प्रतिलिपि में priate स्थिति थोड़ा counterintuitive।
object losToInt extends shapeless.Poly1 {
implicit val atList: Case.Aux[List[Int], Int] = at {
case 0 :: second :: Nil => second
case first :: Nil => first
case Nil => -1
case other => other.sum
}
implicit val atString: Case.Aux[String, Int] = at(_.toInt)
}
def f(a: ListOrString): Int = a.fold(losToInt)
अब संकलक आप असंभव मामलों को संभालने के लिए बिना exhaustivity सत्यापित करेंगे:
सामान्य तौर पर यह एक बहुरूपी समारोह मूल्य के साथ coproduct से अधिक गुना बेहतर है।
स्रोत
2015-12-05 19:05:22
मैं समझने के लिए 'मामले लीग (0 :: दूसरा :: शून्य) => second' वास्तव में है संघर्ष। यदि यह एक प्रोडक्ट है, निश्चित रूप से यह '0' और' second' दोनों नहीं हो सकता है तो यह मैच कब होता है? – fommil
@fommil 'इनल' के अंदर का हिस्सा सिर्फ एक सादा पुरानी सूची से मेल खाता है, इसलिए यह किसी भी समय' प्रोडक्ट [ListOrString] (xs) 'से मेल खाता है, जहां 'xs' में वास्तव में दो तत्व हैं और' 0' है पहले वाला। –
ओह, मैं देखता हूं, धन्यवाद – fommil